├── .eslintrc.json
├── .github
├── ISSUE_TEMPLATE
│ ├── answer.md
│ ├── bug.md
│ ├── feature_request.md
│ ├── feedback.md
│ └── new.md
└── workflows
│ ├── index-update.yml
│ ├── issue-pr.yml
│ └── labeling.yml
├── .gitignore
├── .husky
└── pre-commit
├── .lintstagedrc.json
├── .prettierrc
├── README.md
├── challenges
├── 1-rtl-icon
│ ├── README.md
│ ├── info.yml
│ ├── template.react.md
│ └── template.vanilla.md
├── 10-classnames
│ ├── README.md
│ ├── info.yml
│ └── template.javascript.md
├── 104-queue-using-stack
│ ├── README.md
│ ├── info.yml
│ └── template.javascript.md
├── 109-jest-spyon
│ ├── README.md
│ ├── info.yml
│ └── template.javascript.md
├── 113-losing-this
│ ├── README.md
│ ├── info.yml
│ └── solution.md
├── 115-foreach-and-this
│ ├── README.md
│ ├── info.yml
│ └── template.javascript.md
├── 117-composibility
│ ├── README.md
│ ├── info.yml
│ └── template.javascript.md
├── 121-f-prototype
│ ├── README.md
│ ├── info.yml
│ └── solution.md
├── 123-f-prototype-and-constructor
│ ├── README.md
│ ├── info.yml
│ └── solution.md
├── 13-isempty
│ ├── README.md
│ ├── info.yml
│ └── template.javascript.md
├── 133-class-and-prototype
│ ├── README.md
│ ├── info.yml
│ └── solution.md
├── 137-overriding-constructor
│ ├── README.md
│ ├── info.yml
│ └── solution.md
├── 141-range
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 145-minby
│ ├── README.md
│ ├── info.yml
│ ├── template.javascript.md
│ └── template.typescript.md
├── 148-clamp
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 152-wait
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 158-shuffle
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 16-re-render
│ ├── README.md
│ ├── info.yml
│ └── template.react.md
├── 161-reject
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 169-re-render-2
│ ├── README.md
│ ├── info.yml
│ └── template.react.md
├── 179-contains-duplicate
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 18-flatten
│ ├── README.md
│ ├── info.yml
│ └── template.javascript.md
├── 183-anagrams
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 188-two-sums
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 191-anagram-groups
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 194-top-k-frequent-elements
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 197-string-encode-and-decode
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 199-products-of-array-excluding-self
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 2-click-outisde
│ ├── README.md
│ ├── info.yml
│ └── template.react.md
├── 20-throttle
│ ├── README.md
│ ├── info.yml
│ └── template.javascript.md
├── 201-longest-consecutive-sequence
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 203-is-palindrome
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 205-three-integer-sum
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 207-max-water-container
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 209-best-time-to-buy-and-sell-stock
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 211-longest-substring-without-repeating-characters
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 213-longest-repeating-substring-with-replacement
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 215-minimum-window-with-characters
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 217-validate-parentheses
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 219-find-minimum-in-rotated-sorted-array
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 221-find-target-in-rotated-sorted-array
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 223-reverse-a-linked-list
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 225-merge-two-sorted-linked-lists
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 227-reorder-linked-list
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 229-remove-node-from-end-of-linked-list
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 231-linked-list-cycle-detection
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 233-merge-k-sorted-linked-lists
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 235-invert-a-binary-tree
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 237-depth-of-binary-tree
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 239-same-binary-tree
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 241-subtree-of-a-binary-tree
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 243-lowest-common-ancestor-in-binary-search-tree
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 245-level-order-traversal-of-binary-tree
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 247-valid-binary-search-tree
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 249-kth-smallest-integer-in-bst
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 251-binary-tree-from-preorder-and-inorder-traversal
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 253-binary-tree-maximum-path-sum
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 255-serialize-and-deserialize-binary-tree
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 257-find-median-in-a-data-stream
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 259-combination-target-sum
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 261-search-for-word
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 263-implement-prefix-tree-trie
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 265-design-word-search-data-structure
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 267-search-for-word-ii
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 269-count-number-of-islands
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 271-clone-graph
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 273-pacific-atlantic-water-flow
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 275-course-schedule
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 277-valid-tree
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 279-count-connected-components
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 281-foreign-dictionary
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 283-climbing-stairs
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 285-house-robber
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 287-house-robber-ii
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 289-longest-palindromic-substring
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 291-palindromic-substrings
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 293-decode-ways
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 295-coin-change
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 297-maximum-product-subarray
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 299-word-break
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 3-use-hover
│ ├── README.md
│ ├── info.yml
│ └── template.react.md
├── 301-longest-increasing-subsequence
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 303-count-paths
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 305-longest-common-subsequence
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 307-maximum-subarray
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 309-jump-game
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 311-insert-new-interval
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 313-merge-intervals
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 315-non-overlapping-intervals
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 317-meeting-schedule
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 319-meeting-schedule-ii
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 32-instanceofclass
│ ├── README.md
│ ├── info.yml
│ └── template.javascript.md
├── 321-rotate-matrix
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 323-spiral-matrix
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 325-set-zeroes-in-matrix
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 327-number-of-one-bits
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 329-counting-bits
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 331-reverse-bits
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 333-missing-number
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 335-sum-of-two-integers
│ ├── README.md
│ ├── info.yml
│ └── template.typescript.md
├── 340-escape-the-overflow-hidden
│ ├── README.md
│ ├── info.yml
│ └── template.static.md
├── 346-promise-order
│ ├── README.md
│ ├── info.yml
│ └── solution.md
├── 348-promise-resolution-order
│ ├── README.md
│ ├── info.yml
│ └── solution.md
├── 35-promise-all
│ ├── README.md
│ ├── info.yml
│ └── template.javascript.md
├── 350-promise-chain-output
│ ├── README.md
│ ├── info.yml
│ └── solution.md
├── 352-promise-chain-output-2
│ ├── README.md
│ ├── info.yml
│ └── solution.md
├── 37-promise-race
│ ├── README.md
│ ├── info.yml
│ └── template.javascript.md
├── 4-use-focus-trap
│ ├── README.md
│ ├── info.yml
│ └── template.react.md
├── 40-layout-1
│ ├── README.md
│ ├── info.yml
│ └── template.vanilla.md
├── 43-promise-any
│ ├── README.md
│ ├── info.yml
│ └── template.javascript.md
├── 45-specificity
│ ├── README.md
│ ├── info.yml
│ └── solution.md
├── 47-checkbox
│ ├── README.md
│ ├── info.yml
│ └── template.vanilla.md
├── 49-holy-grail
│ ├── README.md
│ ├── info.yml
│ └── template.vanilla.md
├── 5-fluid-typography
│ ├── README.md
│ ├── info.yml
│ └── template.vanilla.md
├── 55-memo
│ ├── README.md
│ ├── info.yml
│ └── template.javascript.md
├── 58-event-emitter
│ ├── README.md
│ ├── info.yml
│ └── template.javascript.md
├── 6-debounce
│ ├── README.md
│ ├── info.yml
│ └── template.javascript.md
├── 61-logical-operators
│ ├── README.md
│ ├── info.yml
│ └── solution.md
├── 66-this
│ ├── README.md
│ ├── info.yml
│ └── solution.md
├── 69-two-functions-one-object
│ ├── README.md
│ ├── info.yml
│ └── template.javascript.md
├── 7-promise-order
│ ├── README.md
│ ├── info.yml
│ └── solution.md
├── 74-array-prototype-filter
│ ├── README.md
│ ├── info.yml
│ └── template.javascript.md
├── 78-array-prototype-map
│ ├── README.md
│ ├── info.yml
│ └── template.javascript.md
├── 8-closure
│ ├── README.md
│ ├── info.yml
│ └── solution.md
├── 82-array-prototype-reduce
│ ├── README.md
│ ├── info.yml
│ └── template.javascript.md
├── 86-chunk
│ ├── README.md
│ ├── info.yml
│ └── template.javascript.md
├── 91-stack
│ ├── README.md
│ ├── info.yml
│ └── template.javascript.md
├── 95-queue
│ ├── README.md
│ ├── info.yml
│ └── template.javascript.md
└── 99-closure-2
│ ├── README.md
│ ├── info.yml
│ └── template.javascript.md
├── locales
└── en.json
├── package.json
├── packages
├── backend
│ ├── package.json
│ └── src
│ │ ├── db
│ │ ├── blogs.ts
│ │ ├── challenges.ts
│ │ ├── fs.ts
│ │ ├── index.ts
│ │ ├── locales.ts
│ │ ├── roadmaps.ts
│ │ └── templates.ts
│ │ ├── index.ts
│ │ └── utils
│ │ ├── index.ts
│ │ └── readme.ts
├── scripts
│ ├── actions
│ │ ├── issue-pr.ts
│ │ ├── labeling.ts
│ │ └── loader.ts
│ ├── generate-play.ts
│ ├── package.json
│ ├── readme.ts
│ ├── templates
│ │ ├── template-javascript
│ │ │ ├── index.js
│ │ │ └── index.test.js
│ │ ├── template-react
│ │ │ ├── App.jsx
│ │ │ ├── index.html
│ │ │ ├── index.jsx
│ │ │ └── styles.css
│ │ ├── template-vanilla
│ │ │ ├── index.html
│ │ │ ├── index.js
│ │ │ └── styles.css
│ │ └── template-vite
│ │ │ ├── .eslintrc.cjs
│ │ │ ├── README.md
│ │ │ ├── _gitignore
│ │ │ ├── index.html
│ │ │ ├── jest.config.json
│ │ │ ├── package.json
│ │ │ ├── public
│ │ │ └── vite.svg
│ │ │ └── vite.config.js
│ ├── types.ts
│ └── utils
│ │ ├── formatToCode.ts
│ │ ├── index.ts
│ │ ├── locales.ts
│ │ ├── toCommentBlock.ts
│ │ ├── toDivider.ts
│ │ ├── toFooter.ts
│ │ ├── toInfoHeader.ts
│ │ └── toLinks.ts
├── shared
│ ├── package.json
│ └── src
│ │ ├── constants.ts
│ │ ├── index.ts
│ │ ├── templates
│ │ ├── common.ts
│ │ ├── index.ts
│ │ ├── react.ts
│ │ ├── static.ts
│ │ ├── svelte.ts
│ │ ├── tests.ts
│ │ ├── typescript.ts
│ │ ├── vanilla.ts
│ │ └── vue.ts
│ │ ├── types
│ │ ├── env.d.ts
│ │ └── index.ts
│ │ └── utils
│ │ ├── helpers.ts
│ │ ├── index.ts
│ │ ├── locales.ts
│ │ ├── questions.ts
│ │ ├── readme.ts
│ │ ├── template.ts
│ │ └── url.ts
└── website
│ ├── analytics
│ ├── analytics.ts
│ ├── events.ts
│ ├── index.ts
│ ├── providers
│ │ └── mixpanel.ts
│ ├── setup.ts
│ └── types.ts
│ ├── app
│ ├── auth
│ │ └── callback
│ │ │ └── route.ts
│ ├── blog
│ │ ├── [slug]
│ │ │ ├── client.tsx
│ │ │ └── page.tsx
│ │ └── page.tsx
│ ├── categories
│ │ └── [category]
│ │ │ └── page.tsx
│ ├── challenges
│ │ ├── CompletionStats.tsx
│ │ ├── [slug]
│ │ │ ├── Breadcrumb.tsx
│ │ │ ├── MarkCompleteButton.tsx
│ │ │ ├── Question.tsx
│ │ │ ├── Quiz.tsx
│ │ │ ├── ShareSolutionButton.tsx
│ │ │ ├── Solution.tsx
│ │ │ ├── TemplateChanger.tsx
│ │ │ ├── client.tsx
│ │ │ └── page.tsx
│ │ ├── client.tsx
│ │ └── page.tsx
│ ├── client.tsx
│ ├── globals.css
│ ├── layout.tsx
│ ├── page.tsx
│ ├── play
│ │ ├── SharePlaygroundButton.tsx
│ │ ├── client.tsx
│ │ ├── loading.tsx
│ │ ├── page.tsx
│ │ └── usePlaygroundLayout.tsx
│ ├── roadmaps
│ │ ├── [slug]
│ │ │ └── page.tsx
│ │ └── page.tsx
│ ├── sitemap.ts
│ └── submit
│ │ ├── question
│ │ ├── Description.tsx
│ │ ├── Step1Fields.tsx
│ │ ├── Step1Header.tsx
│ │ ├── Step2Fields.tsx
│ │ ├── Step2Header.tsx
│ │ ├── client.tsx
│ │ ├── loading.tsx
│ │ └── page.tsx
│ │ └── quiz
│ │ ├── Step1Header.tsx
│ │ ├── Step2Fields.tsx
│ │ ├── Step2Header.tsx
│ │ ├── client.tsx
│ │ ├── loading.tsx
│ │ └── page.tsx
│ ├── components.json
│ ├── components
│ ├── auth
│ │ ├── SignInButton.tsx
│ │ ├── UserDropdown.tsx
│ │ └── UserNav.tsx
│ ├── blog
│ │ └── BlogList.tsx
│ ├── challenges
│ │ ├── ChallengeList.tsx
│ │ ├── ChallengeListFilterMobile.tsx
│ │ ├── ChallengeListItem.tsx
│ │ ├── ChallengeListSort.tsx
│ │ ├── ChallengeListWithFilters.tsx
│ │ ├── filters-mobile
│ │ │ ├── ChallengeCategoryFilterMobile.tsx
│ │ │ ├── ChallengeDifficultyFilterMobile.tsx
│ │ │ └── ChallengeTypeFilterMobile.tsx
│ │ └── filters
│ │ │ ├── ChallengeCategoryFilter.tsx
│ │ │ ├── ChallengeDifficultyFilter.tsx
│ │ │ ├── ChallengeSearchFilter.tsx
│ │ │ └── ChallengeTypeFilter.tsx
│ ├── common
│ │ ├── CompletionStats.tsx
│ │ ├── LocaleSwitcher.tsx
│ │ ├── Logo.tsx
│ │ ├── MDXComponent.tsx
│ │ ├── Spotlight.tsx
│ │ ├── SubmissionNavigator.tsx
│ │ └── ThemeChanger.tsx
│ ├── editor
│ │ ├── CodeEditor.tsx
│ │ ├── Console.tsx
│ │ ├── Description.tsx
│ │ ├── EditDropdown.tsx
│ │ ├── FileExplorer.tsx
│ │ ├── MonacoEditor.tsx
│ │ ├── Notes.tsx
│ │ ├── Preview.tsx
│ │ ├── ResizableLayout.tsx
│ │ ├── ResizableLayoutTab.tsx
│ │ ├── SandpackLocalProvider.tsx
│ │ ├── SandpackRoot.tsx
│ │ ├── TemplateChanger.tsx
│ │ ├── components
│ │ │ └── DropZoneIndicator.tsx
│ │ └── types.ts
│ ├── home
│ │ ├── CategoryList.tsx
│ │ ├── Community.tsx
│ │ ├── Hero.tsx
│ │ ├── HeroImage.tsx
│ │ └── RecentlyAddedChallenges.tsx
│ ├── icons
│ │ ├── ArrowDownIcon.tsx
│ │ ├── ArrowUpIcon.tsx
│ │ ├── BlogIcon.tsx
│ │ ├── BugIcon.tsx
│ │ ├── ChallengeIcon.tsx
│ │ ├── CheckIcon.tsx
│ │ ├── ChevronDownIcon.tsx
│ │ ├── ChevronLeftIcon.tsx
│ │ ├── ChevronRightIcon.tsx
│ │ ├── ChevronUpIcon.tsx
│ │ ├── CollapseHorizontalIcon.tsx
│ │ ├── CollapseVerticalIcon.tsx
│ │ ├── CssColorIcon.tsx
│ │ ├── EditIcon.tsx
│ │ ├── ExpandHorizontalIcon.tsx
│ │ ├── ExpandVerticalIcon.tsx
│ │ ├── ExternalLinkIcon.tsx
│ │ ├── FilterIcon.tsx
│ │ ├── HomeIcon.tsx
│ │ ├── JavascriptColorIcon.tsx
│ │ ├── Layout1Icon.tsx
│ │ ├── Layout2Icon.tsx
│ │ ├── Layout3Icon.tsx
│ │ ├── LinkedinIcon.tsx
│ │ ├── ListIcon.tsx
│ │ ├── LockIcon.tsx
│ │ ├── LogAllIcon.tsx
│ │ ├── LogClearIcon.tsx
│ │ ├── LogErrorIcon.tsx
│ │ ├── LogInfoIcon.tsx
│ │ ├── LogiWarningIcon.tsx
│ │ ├── MarkdownIcon.tsx
│ │ ├── MoonIcon.tsx
│ │ ├── ReactColorIcon.tsx
│ │ ├── SettingsIcon.tsx
│ │ ├── SortIcon.tsx
│ │ ├── SpinnerIcon.tsx
│ │ ├── SvelteColorIcon.tsx
│ │ ├── SystemIcon.tsx
│ │ ├── TidyIcon.tsx
│ │ ├── TypescriptColorIcon.tsx
│ │ ├── UserIcon.tsx
│ │ ├── VanillaColorIcon.tsx
│ │ ├── VerticalDotsIcon.tsx
│ │ ├── VueColorIcon.tsx
│ │ ├── XIcon.tsx
│ │ └── index.tsx
│ ├── layout
│ │ ├── Footer.tsx
│ │ ├── Header.tsx
│ │ └── Layout.tsx
│ ├── markdown
│ │ ├── Paragraph.tsx
│ │ ├── Pre.tsx
│ │ └── index.tsx
│ ├── mdx
│ │ ├── Sandpack.tsx
│ │ └── index.tsx
│ ├── questions
│ │ ├── AnswerList.tsx
│ │ └── LayoutChanger.tsx
│ ├── roadmaps
│ │ └── RoadmapListItem.tsx
│ └── ui
│ │ ├── accordion.tsx
│ │ ├── alert-dialog.tsx
│ │ ├── alert.tsx
│ │ ├── aspect-ratio.tsx
│ │ ├── avatar.tsx
│ │ ├── badge.tsx
│ │ ├── breadcrumb.tsx
│ │ ├── button.tsx
│ │ ├── calendar.tsx
│ │ ├── card.tsx
│ │ ├── checkbox-button.tsx
│ │ ├── checkbox.tsx
│ │ ├── collapsible.tsx
│ │ ├── command.tsx
│ │ ├── context-menu.tsx
│ │ ├── dialog.tsx
│ │ ├── dropdown-menu.tsx
│ │ ├── form.tsx
│ │ ├── hover-card.tsx
│ │ ├── icon-button.tsx
│ │ ├── icon.tsx
│ │ ├── index.ts
│ │ ├── input.tsx
│ │ ├── label.tsx
│ │ ├── link.tsx
│ │ ├── menubar.tsx
│ │ ├── multi-select.tsx
│ │ ├── navigation-menu.tsx
│ │ ├── popover.tsx
│ │ ├── progress.tsx
│ │ ├── radio-group.tsx
│ │ ├── resizable.tsx
│ │ ├── scroll-area.tsx
│ │ ├── select.tsx
│ │ ├── separator.tsx
│ │ ├── sheet.tsx
│ │ ├── skeleton.tsx
│ │ ├── slider.tsx
│ │ ├── switch.tsx
│ │ ├── table.tsx
│ │ ├── tabs.tsx
│ │ ├── textarea.tsx
│ │ ├── toast.tsx
│ │ ├── toaster.tsx
│ │ ├── toggle-group.tsx
│ │ ├── toggle.tsx
│ │ ├── tooltip.tsx
│ │ └── use-toast.ts
│ ├── content
│ └── blog
│ │ └── how-to-contribute
│ │ └── index.md
│ ├── contexts
│ └── DragDropContext.tsx
│ ├── db
│ ├── answers.ts
│ ├── auth.ts
│ ├── completions.ts
│ └── notes.ts
│ ├── hooks
│ ├── index.ts
│ ├── useAnalytics.ts
│ ├── useAnswers.ts
│ ├── useAuth.ts
│ ├── useChallengeFiles.ts
│ ├── useCompletions.ts
│ ├── useDebounce.ts
│ ├── useFilteredChallenges.ts
│ ├── useInitializeFilters.ts
│ ├── useLocalStorage.ts
│ ├── useMobile.ts
│ ├── useNotes.ts
│ ├── usePrettify.ts
│ ├── useScrollableTabs.ts
│ ├── useStats.ts
│ ├── useSyncScopeToSessionStorage.ts
│ └── utils
│ │ └── useForceUpdate.ts
│ ├── next.config.js
│ ├── package.json
│ ├── postcss.config.js
│ ├── providers
│ ├── AuthProvider.tsx
│ ├── ChallengesProvider.tsx
│ ├── LayoutProvider.tsx
│ ├── QueryProvider.tsx
│ ├── ThemeProvider.tsx
│ └── index.tsx
│ ├── public
│ ├── favicon.ico
│ ├── images
│ │ ├── auth-github-bg.png
│ │ ├── logo-2.png
│ │ ├── logo-readme-dark.png
│ │ ├── logo-readme-dark.svg
│ │ ├── logo-readme-light.png
│ │ ├── logo-readme-light.svg
│ │ └── logo.svg
│ ├── og.png
│ ├── questions
│ │ └── rtl-icon-1.png
│ └── robots.txt
│ ├── store
│ └── ui.ts
│ ├── tailwind.config.js
│ ├── tsconfig.json
│ └── utils
│ ├── answers.ts
│ ├── categories.ts
│ ├── challenges.ts
│ ├── helpers.ts
│ ├── localStorage.ts
│ ├── markdown.ts
│ ├── mixpanel.ts
│ ├── sessionStorage.ts
│ └── supabase
│ ├── client.ts
│ ├── middleware.ts
│ └── server.ts
├── pnpm-lock.yaml
├── pnpm-workspace.yaml
├── roadmaps
├── blind75
│ └── info.yml
└── javascript
│ └── info.yml
└── tsconfig.json
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json.schemastore.org/eslintrc",
3 | "root": true,
4 | "parser": "@typescript-eslint/parser",
5 | "plugins": ["react", "@typescript-eslint", "prettier", "react-hooks", "sort-destructure-keys"],
6 | "extends": [
7 | "plugin:react/recommended", // Uses the recommended rules from @eslint-plugin-react
8 | "plugin:@typescript-eslint/recommended",
9 | // Note: Please keep this as the last config to make sure that this (and by extension our .prettierrc file) overrides all configuration above it
10 | // https://www.npmjs.com/package/eslint-plugin-prettier#recommended-configuration
11 | "plugin:prettier/recommended"
12 | ],
13 | "rules": {
14 | "react/react-in-jsx-scope": "off",
15 | "react/prop-types": "off",
16 | "@typescript-eslint/no-explicit-any": "off"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/answer.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Answers
3 | about: Share answers/solutions to a question
4 | title: "no - "
5 | labels: answer, en
6 | ---
7 |
8 |
19 |
20 | ```ts
21 | // your answers
22 | ```
23 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: '[Bug]: ...'
5 | labels: bug
6 | assignees: jsartisan
7 | ---
8 |
9 | **Describe the bug**
10 | A clear and concise description of what the bug is.
11 |
12 | **To Reproduce**
13 | Steps to reproduce the behavior:
14 |
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 |
27 | **Additional context**
28 | Add any other context about the problem here.
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: enhancement
6 | assignees: markmead
7 | ---
8 |
9 | **Is your feature request related to a problem? Please describe.**
10 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
11 |
12 | **Describe the solution you'd like**
13 | A clear and concise description of what you want to happen.
14 |
15 | **Describe alternatives you've considered**
16 | A clear and concise description of any alternative solutions or features you've considered.
17 |
18 | **Additional context**
19 | Add any other context or screenshots about the feature request here.
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feedback.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feedback
3 | about: Provide feedback on the site
4 | title: '[Feedback]: ...'
5 | labels: feedback
6 | assignees: jsartisan
7 | ---
8 |
9 | ### 💡 Site Feedback
10 |
11 | **Your Feedback**
12 | Please provide your thoughts, ideas, or suggestions to improve the site.
13 |
14 | **What did you like?**
15 | Tell us what you liked about the site!
16 |
17 | **What could be improved?**
18 | Share any areas you think could be improved or enhanced.
19 |
20 | **Additional context**
21 | Add any other comments or suggestions, such as features you'd like to see or changes that would improve the user experience.
22 |
--------------------------------------------------------------------------------
/.github/workflows/index-update.yml:
--------------------------------------------------------------------------------
1 | name: Index Update
2 |
3 | on:
4 | schedule:
5 | - cron: "0 0 * * *"
6 | workflow_dispatch: {}
7 |
8 | jobs:
9 | start:
10 | env:
11 | NODE_ENV: ${{ secrets.NODE_ENV }}
12 | NEXT_BASE_URL: ${{ secrets.NEXT_BASE_URL }}
13 | runs-on: ubuntu-latest
14 | steps:
15 | - uses: actions/checkout@v3
16 | - uses: pnpm/action-setup@v2
17 | with:
18 | version: 9.6.0
19 | - uses: actions/setup-node@v3
20 | with:
21 | node-version: 18.x
22 | cache: pnpm
23 | - run: pnpm i
24 | - run: npm run readme
25 | - uses: EndBug/add-and-commit@v9
26 | with:
27 | message: "chore: update index"
28 |
--------------------------------------------------------------------------------
/.github/workflows/issue-pr.yml:
--------------------------------------------------------------------------------
1 | name: Issue to Pull Request
2 |
3 | on:
4 | issues:
5 | types: [opened, edited]
6 |
7 | jobs:
8 | start:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: actions/checkout@v3
12 | - uses: pnpm/action-setup@v2
13 | with:
14 | version: 9.6.0
15 | - uses: actions/setup-node@v3
16 | with:
17 | node-version: 18.x
18 | cache: pnpm
19 | - run: pnpm i
20 | - run: cd packages/scripts/actions && npx esno ./loader.ts ${{github.token}} issue-pr
21 |
--------------------------------------------------------------------------------
/.github/workflows/labeling.yml:
--------------------------------------------------------------------------------
1 | name: Labeling
2 |
3 | on:
4 | issues:
5 | types: [opened, labeled]
6 |
7 | jobs:
8 | start:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: actions/checkout@v3
12 | - uses: pnpm/action-setup@v2
13 | with:
14 | version: 9.6.0
15 | - uses: actions/setup-node@v3
16 | with:
17 | node-version: 18.x
18 | cache: pnpm
19 | - run: pnpm i
20 | - run: cd packages/scripts/actions && npx esno ./loader.ts ${{github.token}} labeling
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | node_modules
5 | /.pnp
6 | .pnp.js
7 | .yarn/install-state.gz
8 |
9 | # testing
10 | /coverage
11 |
12 | # next.js
13 | .next/
14 | /out/
15 |
16 | # production
17 | /build
18 |
19 | # misc
20 | .DS_Store
21 | *.pem
22 | .eslintcache
23 |
24 | # debug
25 | npm-debug.log*
26 | yarn-debug.log*
27 | yarn-error.log*
28 |
29 | # local env files
30 | .env*
31 | .env*.local
32 |
33 | # vercel
34 | .vercel
35 |
36 | # typescript
37 | *.tsbuildinfo
38 | next-env.d.ts
39 |
40 | # playground
41 | /playground
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | npx lint-staged
2 |
--------------------------------------------------------------------------------
/.lintstagedrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "*.{js,ts,tsx}": ["eslint --fix --cache"],
3 | "*.{css,json}": ["prettier --write --cache"]
4 | }
5 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "printWidth": 120,
3 | "tabWidth": 2,
4 | "useTabs": false,
5 | "semi": true,
6 | "singleQuote": false,
7 | "trailingComma": "all",
8 | "arrowParens": "always",
9 | "plugins": [
10 | "prettier-plugin-tailwindcss"
11 | ],
12 | "tailwindFunctions": [
13 | "clsx"
14 | ]
15 | }
--------------------------------------------------------------------------------
/challenges/1-rtl-icon/info.yml:
--------------------------------------------------------------------------------
1 | title: Icon and RTL
2 | excerpt: Fix the broken icon in RTL mode.
3 | difficulty: easy
4 | author:
5 | name: Pawan Kumar
6 | email: pawankumar2901@gmail.com
7 | github: jsartisan
8 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
9 | tags: css, logical properties
10 | resources:
11 | - https://developer.mozilla.org/en-US/docs/Web/CSS/margin-inline-start
12 | - https://css-tricks.com/almanac/properties/g/gap/
13 | template: vanilla
14 | published_date: 2024-01-03
--------------------------------------------------------------------------------
/challenges/10-classnames/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: classNames
3 | template: javascript
4 | tags: javascript
5 | author:
6 | github: jsartisan
7 | name: Pawan Kumar
8 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
9 | published_date: '2024-02-21'
10 |
11 |
--------------------------------------------------------------------------------
/challenges/104-queue-using-stack/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: Queue using Stack
3 | type: question
4 | template: javascript
5 | tags: javascript
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-07-02'
11 | discussionNo: 108
12 |
13 |
--------------------------------------------------------------------------------
/challenges/109-jest-spyon/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: jest.spyOn
3 | type: question
4 | template: javascript
5 | tags: javascript
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-07-08'
11 | discussionNo: 111
12 |
13 |
--------------------------------------------------------------------------------
/challenges/113-losing-this/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: Losing this
3 | type: quiz
4 | tags: javascript
5 | author:
6 | github: jsartisan
7 | name: Pawan Kumar
8 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
9 | published_date: '2024-07-17'
10 |
11 |
--------------------------------------------------------------------------------
/challenges/113-losing-this/solution.md:
--------------------------------------------------------------------------------
1 | When `user.sayHi` is passed to setTimeout, it is detached from the user object. Therefore, when setTimeout calls this function, it does so without any context, causing this to be undefined.
2 |
3 | Solution:
4 | Here are a few ways to fix this issue:
5 |
6 | **1. Using bind:**
7 | ```js
8 | let user = {
9 | firstName: "John",
10 | sayHi() {
11 | alert(`Hello, ${this.firstName}!`);
12 | }
13 | };
14 |
15 | setTimeout(user.sayHi.bind(user), 1000); // Hello, John!
16 | ```
17 |
18 | **2. Using an arrow function:**
19 | ```
20 | let user = {
21 | firstName: "John",
22 | sayHi() {
23 | alert(`Hello, ${this.firstName}!`);
24 | }
25 | };
26 |
27 | setTimeout(() => user.sayHi(), 1000); // Hello, John!
28 | ```
29 |
30 | **3. Using a wrapper function:**
31 |
32 | ```js
33 | let user = {
34 | firstName: "John",
35 | sayHi() {
36 | alert(`Hello, ${this.firstName}!`);
37 | }
38 | };
39 |
40 | setTimeout(function() {
41 | user.sayHi();
42 | }, 1000); // Hello, John!
43 |
44 | ```
45 |
--------------------------------------------------------------------------------
/challenges/115-foreach-and-this/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: forEach and this
3 | type: question
4 | template: javascript
5 | tags: javascript
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-07-25'
11 | discussionNo: 120
12 |
13 |
--------------------------------------------------------------------------------
/challenges/117-composibility/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: Composibility
3 | type: question
4 | template: javascript
5 | tags: javascript
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-07-25'
11 | discussionNo: 127
12 |
13 |
--------------------------------------------------------------------------------
/challenges/117-composibility/template.javascript.md:
--------------------------------------------------------------------------------
1 | ```js index.js
2 | function User(name, birthday) {
3 | this.name = name;
4 | this.birthday = birthday;
5 | }
6 |
7 | export { User };
8 | ```
9 |
10 | ```js index.test.js
11 | import { User } from './index';
12 |
13 | describe('User constructor', () => {
14 | test('should correctly calculate age', () => {
15 | const user = new User("Pawan Kumar", new Date(1993, 1, 29));
16 |
17 | expect(user.age).toBe(31);
18 | });
19 |
20 | test('should update age if birthday is updated', () => {
21 | let person = new User("Pawan Kumar", new Date(1995, 6, 15)); // July 15, 1995
22 | expect(person.age).toBe(29);
23 |
24 | // Update the birthday
25 | person.birthday = new Date(2000, 6, 15); // July 15, 2000
26 | expect(person.age).toBe(24);
27 | });
28 | });
29 | ```
30 |
31 |
32 |
--------------------------------------------------------------------------------
/challenges/121-f-prototype/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: F.prototype
3 | type: quiz
4 | tags: javascript
5 | author:
6 | github: jsartisan
7 | name: Pawan Kumar
8 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
9 | published_date: '2024-07-27'
10 | discussionNo: 125
11 |
12 |
--------------------------------------------------------------------------------
/challenges/121-f-prototype/solution.md:
--------------------------------------------------------------------------------
1 | The output will be:
2 | ```
3 | true
4 | true
5 | false
6 | ```
7 |
8 | - `rabbit1.eats` logs `true` because `rabbit1` is created when `Rabbit.prototype` has `eats` set to `true`.
9 | - `rabbit1.eats` logs `true` again because reassigning `Rabbit.prototype` creates a new prototype object but does not affect existing instances.
10 | - `rabbit2.eats` logs `false` because `rabbit2` is created after `Rabbit.prototype` is reassigned to a new object with `eats` set to `false`.
11 |
--------------------------------------------------------------------------------
/challenges/123-f-prototype-and-constructor/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: F.prototype and constructor
3 | type: quiz
4 | tags: javascript
5 | author:
6 | github: jsartisan
7 | name: Pawan Kumar
8 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
9 | published_date: '2024-07-27'
10 | discussionNo: 126
11 |
12 |
--------------------------------------------------------------------------------
/challenges/13-isempty/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: IsEmpty
3 | template: javascript
4 | tags: javascript, lodash
5 | author:
6 | github: albinAppsmith
7 | name: Albin
8 | avatar_url: https://avatars.githubusercontent.com/u/87797149?v=4
9 | published_date: '2024-02-21'
10 |
11 |
--------------------------------------------------------------------------------
/challenges/133-class-and-prototype/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: Class and Prototype
3 | type: quiz
4 | tags: javascript
5 | author:
6 | github: jsartisan
7 | name: Pawan Kumar
8 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
9 | published_date: '2024-07-29'
10 | discussionNo: 135
11 |
12 |
--------------------------------------------------------------------------------
/challenges/133-class-and-prototype/solution.md:
--------------------------------------------------------------------------------
1 | ```bash
2 | function
3 | {
4 | constructor: [Function: User],
5 | greet: [Function: greet]
6 | }
7 | [Function: User]
8 | ['constructor', 'greet']
9 | ```
10 |
11 | ### Explanation
12 |
13 | 1. `typeof User`:
14 | - In JavaScript, classes are syntactic sugar over constructor functions, so `typeof User` will return `"function".
15 |
16 | 2. `User.prototype`:
17 | - Shows an object with properties `constructor` and `greet`. The `constructor` property references the `User` function itself.
18 |
19 | 3. `User.prototype.constructor`:
20 | - Shows the `User` function, indicating that the `constructor` property points to the `User` function.
21 |
22 | 4. `Object.getOwnPropertyNames(User.prototype)`:
23 | - Returns an array of the property names directly found on `User.prototype`, which are `constructor` and `greet`.
24 |
--------------------------------------------------------------------------------
/challenges/137-overriding-constructor/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: Overriding constructor
3 | type: quiz
4 | tags: javascript
5 | author:
6 | github: jsartisan
7 | name: Pawan Kumar
8 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
9 | published_date: '2024-08-02'
10 | discussionNo: 139
11 |
12 |
--------------------------------------------------------------------------------
/challenges/137-overriding-constructor/solution.md:
--------------------------------------------------------------------------------
1 | The error occurs because the `Student` class constructor does not call the `super` constructor of the `Person` class. In JavaScript, when a class extends another class, the derived class's constructor must call `super()` before accessing `this`.
2 |
3 | To fix this, you need to call `super(name)` in the `Student` constructor before you can use `this`. Here's the corrected code:
4 |
5 | ```js
6 | class Person {
7 | constructor(name) {
8 | this.name = name;
9 | }
10 | }
11 |
12 | class Student extends Person {
13 | constructor(name, studentId) {
14 | // Call the constructor of the Person class
15 | super(name);
16 | this.studentId = studentId;
17 | }
18 | }
19 |
20 | // Works correctly now
21 | let student = new Student("Pawan Kumar", 1);
22 | console.log(student.name); // Output: Pawan Kumar
23 | console.log(student.studentId); // Output: 1
24 | ```
25 |
--------------------------------------------------------------------------------
/challenges/141-range/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: range
3 | type: question
4 | template: typescript
5 | tags: javascript
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-08-08'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/145-minby/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: minBy
3 | type: question
4 | template: typescript
5 | tags: javascript
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-08-09'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/148-clamp/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: clamp
3 | type: question
4 | template: typescript
5 | tags: javascript
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-08-09'
11 | discussionNo: 150
12 |
13 |
--------------------------------------------------------------------------------
/challenges/152-wait/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: wait
3 | type: question
4 | template: typescript
5 | tags: javascript
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-08-09'
11 | discussionNo: 154
12 |
13 |
--------------------------------------------------------------------------------
/challenges/158-shuffle/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: shuffle
3 | type: question
4 | template: typescript
5 | tags: javascript
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-08-10'
11 | discussionNo: 160
12 |
13 |
--------------------------------------------------------------------------------
/challenges/16-re-render/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: re-render
3 | type: question
4 | template: react
5 | tags: react, performance
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-09-08'
--------------------------------------------------------------------------------
/challenges/161-reject/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: reject
3 | type: question
4 | template: typescript
5 | tags: javascript
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-08-12'
11 | discussionNo: 163
12 |
13 |
--------------------------------------------------------------------------------
/challenges/169-re-render-2/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: re-render 2
3 | type: question
4 | template: react
5 | tags: react,performance
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-09-08'
11 | discussionNo: 171
12 |
13 |
--------------------------------------------------------------------------------
/challenges/179-contains-duplicate/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: Contains Duplicate
3 | type: question
4 | template: typescript
5 | tags: javascript,blind75
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-10-13'
11 | discussionNo: 181
12 |
13 |
--------------------------------------------------------------------------------
/challenges/18-flatten/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: flatten
3 | template: javascript
4 | tags: javascript, utility, lodash
5 | author:
6 | github: jsartisan
7 | name: Pawan Kumar
8 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
9 | published_date: '2024-02-28'
10 |
11 |
--------------------------------------------------------------------------------
/challenges/18-flatten/template.javascript.md:
--------------------------------------------------------------------------------
1 | ```js index.js
2 | export function flatten(arr, depth = 1) {
3 | // write your logic here
4 | }
5 | ```
6 |
7 | ```js index.test.js
8 | import { flatten } from './index';
9 |
10 | describe('flatten function', () => {
11 | test('should flatten the array by default depth', () => {
12 | const arr = [1, [2], [3, [4]]];
13 | expect(flatten(arr)).toEqual([1, 2, 3, [4]]);
14 | });
15 |
16 | test('should flatten the array by specified depth', () => {
17 | const arr = [1, [2], [3, [4]]];
18 | expect(flatten(arr, 1)).toEqual([1, 2, 3, [4]]);
19 | expect(flatten(arr, 2)).toEqual([1, 2, 3, 4]);
20 | expect(flatten(arr, 0)).toEqual([1, [2], [3, [4]]]);
21 | });
22 |
23 | test('should handle Infinity depth', () => {
24 | const arr = [1, [2], [3, [4]]];
25 | expect(flatten(arr, Infinity)).toEqual([1, 2, 3, 4]);
26 | });
27 |
28 | test('should handle deeply nested arrays', () => {
29 | const arr = [1, [2, [3, [4, [5]]]]];
30 | expect(flatten(arr, 3)).toEqual([1, 2, 3, 4, [5]]);
31 | });
32 | });
33 | ```
34 |
35 |
36 |
--------------------------------------------------------------------------------
/challenges/183-anagrams/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: Anagrams
3 | type: question
4 | template: typescript
5 | tags: javascrip,arrays,blind75
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-10-13'
11 | discussionNo: 185
12 |
13 |
--------------------------------------------------------------------------------
/challenges/188-two-sums/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: Two Sums
3 | type: question
4 | template: typescript
5 | tags: javascript,blind75
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-10-13'
11 | discussionNo: 190
12 |
13 |
--------------------------------------------------------------------------------
/challenges/191-anagram-groups/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Anagram Groups
3 | type: question
4 | template: typescript
5 | tags: javascript,blind75
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-10-17'
11 | discussionNo: 193
12 |
13 |
--------------------------------------------------------------------------------
/challenges/194-top-k-frequent-elements/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Top K Frequent Elements
3 | type: question
4 | template: typescript
5 | tags: javascript,blind75
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-01'
11 | discussionNo: 196
12 |
13 |
--------------------------------------------------------------------------------
/challenges/194-top-k-frequent-elements/template.typescript.md:
--------------------------------------------------------------------------------
1 | ```ts index.ts
2 | export function topKFrequent(nums: number[], k: number): number[] {}
3 |
4 | ```
5 |
6 | ```ts index.test.ts
7 | import { topKFrequent } from "./index";
8 |
9 | describe("topKFrequent", () => {
10 | test("should return top k frequent elements", () => {
11 | expect(topKFrequent([1, 2, 2, 3, 3, 3], 2)).toEqual(
12 | expect.arrayContaining([2, 3]),
13 | );
14 | expect(topKFrequent([7, 7], 1)).toEqual([7]);
15 | });
16 |
17 | test("should handle elements with same frequency", () => {
18 | expect(topKFrequent([1, 1, 2, 2, 3], 2)).toEqual(
19 | expect.arrayContaining([1, 2]),
20 | );
21 | });
22 |
23 | test("should handle single element", () => {
24 | expect(topKFrequent([1], 1)).toEqual([1]);
25 | });
26 |
27 | test("should handle all unique elements", () => {
28 | expect(topKFrequent([1, 2, 3, 4], 2)).toEqual(
29 | expect.arrayContaining([1, 2]),
30 | );
31 | });
32 | });
33 |
34 | ```
35 |
36 |
37 |
--------------------------------------------------------------------------------
/challenges/197-string-encode-and-decode/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: String encode and decode
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-01'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/199-products-of-array-excluding-self/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Products of Array Excluding Self
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, array
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-01'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/199-products-of-array-excluding-self/template.typescript.md:
--------------------------------------------------------------------------------
1 | ```ts index.ts
2 | export function productExceptSelf(nums: number[]): number[] {
3 |
4 | }
5 | ```
6 |
7 | ```ts index.test.ts
8 | import { productExceptSelf } from './index';
9 |
10 | describe('productExceptSelf', () => {
11 | test('Example 1: Basic positive numbers', () => {
12 | expect(productExceptSelf([1, 2, 4, 6]))
13 | .toEqual([48, 24, 12, 8]);
14 | });
15 |
16 | test('Example 2: Array with zero', () => {
17 | expect(productExceptSelf([-1, 0, 1, 2, 3]))
18 | .toEqual([0, -6, 0, 0, 0]);
19 | });
20 |
21 | test('Array with two elements', () => {
22 | expect(productExceptSelf([2, 3]))
23 | .toEqual([3, 2]);
24 | });
25 |
26 | test('Array with negative numbers', () => {
27 | expect(productExceptSelf([-2, -3, -4]))
28 | .toEqual([12, 8, 6]);
29 | });
30 |
31 | test('Array with multiple zeros', () => {
32 | expect(productExceptSelf([0, 0, 2]))
33 | .toEqual([0, 0, 0]);
34 | });
35 | });
36 | ```
37 |
38 |
39 |
--------------------------------------------------------------------------------
/challenges/2-click-outisde/info.yml:
--------------------------------------------------------------------------------
1 | title: useClickOutside
2 | excerpt: Implement a custom hook that listens for clicks outside of a given element.
3 | author:
4 | name: Pawan Kumar
5 | email: pawankumar2901@gmail.com
6 | github: jsartisan
7 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
8 | tags: react, event listeners, hooks
9 | template: react
10 | difficulty: easy
11 |
--------------------------------------------------------------------------------
/challenges/2-click-outisde/template.react.md:
--------------------------------------------------------------------------------
1 | ```js App.jsx
2 | import { useRef } from "react";
3 | import useClickOutside from "./useClickOutside";
4 |
5 | function App() {
6 | const ref = useRef(null);
7 |
8 | useClickOutside(ref, () => {
9 | alert("clicked outside");
10 | });
11 |
12 | return (
13 |
14 |
Click outside React
15 |
16 | );
17 | }
18 |
19 | export default App;
20 | ```
21 |
22 | ```js useClickOutside.js active
23 | import { useEffect } from "react";
24 |
25 | const useClickOutside = (ref, callback) => {
26 |
27 | };
28 |
29 | export default useClickOutside;
30 | ```
31 |
--------------------------------------------------------------------------------
/challenges/20-throttle/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: hard
2 | title: throttle
3 | template: javascript
4 | tags: utility, lodash, javascript
5 | author:
6 | github: jsartisan
7 | name: Pawan Kumar
8 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
9 | published_date: '2024-02-28'
10 |
11 |
--------------------------------------------------------------------------------
/challenges/20-throttle/template.javascript.md:
--------------------------------------------------------------------------------
1 | ```js index.js
2 | export function throttle(cb, delay = 250) {
3 | // your answer here
4 | }
5 | ```
6 |
7 | ```js index.test.js
8 | import { throttle } from './index';
9 |
10 | function wait(time) {
11 | return new Promise((resolve) => setTimeout(resolve, time));
12 | }
13 |
14 | describe('throttle function', () => {
15 | it('should throttle function calls', async () => {
16 |
17 | const mockFunction = jest.fn();
18 |
19 | const throttledFunction = throttle(mockFunction, 500);
20 |
21 | throttledFunction();
22 | throttledFunction();
23 | throttledFunction();
24 |
25 | await wait(600);
26 | expect(mockFunction).toHaveBeenCalledTimes(1);
27 | });
28 |
29 | it('should pass arguments correctly', async () => {
30 | const mockFunction = jest.fn();
31 |
32 | const throttledFunction = throttle(mockFunction, 500);
33 |
34 | throttledFunction(1);
35 | throttledFunction(2);
36 |
37 | await wait(600);
38 | expect(mockFunction).toHaveBeenCalledWith(1);
39 | });
40 | });
41 | ```
42 |
43 |
44 |
--------------------------------------------------------------------------------
/challenges/201-longest-consecutive-sequence/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Longest Consecutive Sequence
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, array, hash-set
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-01'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/201-longest-consecutive-sequence/template.typescript.md:
--------------------------------------------------------------------------------
1 | ```ts index.ts
2 | export function longestConsecutive(nums: number[]): number {
3 |
4 | }
5 | ```
6 |
7 | ```ts index.test.ts
8 | import { longestConsecutive } from './index';
9 |
10 | describe('longestConsecutive', () => {
11 | test('Example 1: Basic sequence', () => {
12 | expect(longestConsecutive([2, 20, 4, 10, 3, 4, 5])).toBe(4);
13 | });
14 |
15 | test('Example 2: Sequence with duplicates', () => {
16 | expect(longestConsecutive([0, 3, 2, 5, 4, 6, 1, 1])).toBe(7);
17 | });
18 |
19 | test('Empty array', () => {
20 | expect(longestConsecutive([])).toBe(0);
21 | });
22 |
23 | test('Single element array', () => {
24 | expect(longestConsecutive([1])).toBe(1);
25 | });
26 |
27 | test('No consecutive sequence', () => {
28 | expect(longestConsecutive([2, 4, 6, 8])).toBe(1);
29 | });
30 |
31 | test('Negative numbers', () => {
32 | expect(longestConsecutive([-5, -4, -3, -2, 0, 1])).toBe(4);
33 | });
34 | });
35 | ```
36 |
37 |
38 |
--------------------------------------------------------------------------------
/challenges/203-is-palindrome/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: Is Palindrome
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, string, two-pointers
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-01'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/205-three-integer-sum/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Three Integer Sum
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, array, two-pointers
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-01'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/207-max-water-container/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Max Water Container
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, array, two-pointers
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-01'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/207-max-water-container/template.typescript.md:
--------------------------------------------------------------------------------
1 | ```ts index.ts
2 | export function maxArea(height: number[]): number {
3 |
4 | }
5 | ```
6 |
7 | ```ts index.test.ts
8 | import { maxArea } from './index';
9 |
10 | describe('maxArea', () => {
11 | test('Example 1: Regular case', () => {
12 | expect(maxArea([1, 7, 2, 5, 4, 7, 3, 6])).toBe(36);
13 | });
14 |
15 | test('Example 2: All same height', () => {
16 | expect(maxArea([2, 2, 2])).toBe(4);
17 | });
18 |
19 | test('Minimum length array', () => {
20 | expect(maxArea([1, 2])).toBe(1);
21 | });
22 |
23 | test('Increasing heights', () => {
24 | expect(maxArea([1, 2, 3, 4, 5])).toBe(6);
25 | });
26 |
27 | test('Decreasing heights', () => {
28 | expect(maxArea([5, 4, 3, 2, 1])).toBe(6);
29 | });
30 |
31 | test('Zero height included', () => {
32 | expect(maxArea([0, 7, 0, 7])).toBe(14);
33 | });
34 |
35 | test('Large difference in heights', () => {
36 | expect(maxArea([1, 1000, 1, 1000, 1])).toBe(3000);
37 | });
38 | });
39 | ```
40 |
41 |
42 |
--------------------------------------------------------------------------------
/challenges/209-best-time-to-buy-and-sell-stock/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: Best Time to Buy and Sell Stock
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, array, dynamic-programming
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-01'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/209-best-time-to-buy-and-sell-stock/template.typescript.md:
--------------------------------------------------------------------------------
1 | ```ts index.ts
2 | export function maxProfit(prices: number[]): number {
3 |
4 | }
5 | ```
6 |
7 | ```ts index.test.ts
8 | import { maxProfit } from './index';
9 |
10 | describe('maxProfit', () => {
11 | test('Example 1: Regular case with profit', () => {
12 | expect(maxProfit([7, 1, 5, 3, 6, 4])).toBe(5);
13 | });
14 |
15 | test('Example 2: Decreasing prices', () => {
16 | expect(maxProfit([7, 6, 4, 3, 1])).toBe(0);
17 | });
18 |
19 | test('Single day', () => {
20 | expect(maxProfit([1])).toBe(0);
21 | });
22 |
23 | test('Two days with profit', () => {
24 | expect(maxProfit([1, 2])).toBe(1);
25 | });
26 |
27 | test('Two days without profit', () => {
28 | expect(maxProfit([2, 1])).toBe(0);
29 | });
30 |
31 | test('Same prices', () => {
32 | expect(maxProfit([5, 5, 5, 5])).toBe(0);
33 | });
34 |
35 | test('Multiple peaks and valleys', () => {
36 | expect(maxProfit([3, 2, 6, 1, 2])).toBe(4);
37 | });
38 | });
39 | ```
40 |
41 |
42 |
--------------------------------------------------------------------------------
/challenges/211-longest-substring-without-repeating-characters/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Longest Substring Without Repeating Characters
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, string, sliding-window, hash-map
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-01'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/213-longest-repeating-substring-with-replacement/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Longest Repeating Substring With Replacement
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, string, sliding-window
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/215-minimum-window-with-characters/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: hard
2 | title: Minimum Window With Characters
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, string, sliding-window, hash-map
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/217-validate-parentheses/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: Validate Parentheses
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, string, stack
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/217-validate-parentheses/template.typescript.md:
--------------------------------------------------------------------------------
1 | ```ts index.ts
2 | export function isValid(s: string): boolean {
3 |
4 | }
5 | ```
6 |
7 | ```ts index.test.ts
8 | import { isValid } from './index';
9 |
10 | describe('isValid', () => {
11 | test('Example 1: Simple valid case', () => {
12 | expect(isValid("[]")).toBe(true);
13 | });
14 |
15 | test('Example 2: Nested valid case', () => {
16 | expect(isValid("([{}])")).toBe(true);
17 | });
18 |
19 | test('Example 3: Invalid order', () => {
20 | expect(isValid("[(])")).toBe(false);
21 | });
22 |
23 | test('Single character', () => {
24 | expect(isValid("[")).toBe(false);
25 | });
26 |
27 | test('Empty string', () => {
28 | expect(isValid("")).toBe(true);
29 | });
30 |
31 | test('Multiple pairs', () => {
32 | expect(isValid("()[]{}")).toBe(true);
33 | });
34 |
35 | test('Mismatched brackets', () => {
36 | expect(isValid("(]")).toBe(false);
37 | });
38 |
39 | test('Complex nested valid case', () => {
40 | expect(isValid("{[]}()")).toBe(true);
41 | });
42 | });
43 | ```
44 |
45 |
46 |
--------------------------------------------------------------------------------
/challenges/219-find-minimum-in-rotated-sorted-array/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Find Minimum in Rotated Sorted Array
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, array, binary-search
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/219-find-minimum-in-rotated-sorted-array/template.typescript.md:
--------------------------------------------------------------------------------
1 | ```ts index.ts
2 | export function findMin(nums: number[]): number {
3 |
4 | }
5 | ```
6 |
7 | ```ts index.test.ts
8 | import { findMin } from './index';
9 |
10 | describe('findMin', () => {
11 | test('Example 1: Regular rotated array', () => {
12 | expect(findMin([3, 4, 5, 6, 1, 2])).toBe(1);
13 | });
14 |
15 | test('Example 2: Array with zero', () => {
16 | expect(findMin([4, 5, 0, 1, 2, 3])).toBe(0);
17 | });
18 |
19 | test('Example 3: Not rotated array', () => {
20 | expect(findMin([4, 5, 6, 7])).toBe(4);
21 | });
22 |
23 | test('Single element array', () => {
24 | expect(findMin([1])).toBe(1);
25 | });
26 |
27 | test('Two element array', () => {
28 | expect(findMin([2, 1])).toBe(1);
29 | });
30 |
31 | test('Array rotated n times', () => {
32 | expect(findMin([1, 2, 3, 4, 5])).toBe(1);
33 | });
34 |
35 | test('Array with negative numbers', () => {
36 | expect(findMin([2, 3, -2, -1, 0, 1])).toBe(-2);
37 | });
38 | });
39 | ```
40 |
41 |
42 |
--------------------------------------------------------------------------------
/challenges/221-find-target-in-rotated-sorted-array/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Find Target in Rotated Sorted Array
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, array, binary-search
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/223-reverse-a-linked-list/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: Reverse a Linked List
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, linked-list
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/225-merge-two-sorted-linked-lists/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: Merge Two Sorted Linked Lists
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, linked-list
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/227-reorder-linked-list/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Reorder Linked List
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, linked-list
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/229-remove-node-from-end-of-linked-list/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Remove Node From End of Linked List
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, linked-list, two-pointers
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/231-linked-list-cycle-detection/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: Linked List Cycle Detection
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, linked-list, two-pointers
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/233-merge-k-sorted-linked-lists/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: hard
2 | title: Merge K Sorted Linked Lists
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, linked-list, heap, divide-and-conquer
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/235-invert-a-binary-tree/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: Invert a Binary Tree
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, binary-tree, recursion
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/237-depth-of-binary-tree/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: Depth of Binary Tree
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, binary-tree, recursion
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/239-same-binary-tree/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: Same Binary Tree
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, binary-tree, recursion
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/241-subtree-of-a-binary-tree/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: Subtree of a Binary Tree
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, binary-tree, recursion
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/243-lowest-common-ancestor-in-binary-search-tree/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Lowest Common Ancestor in Binary Search Tree
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, binary-search-tree, recursion
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/245-level-order-traversal-of-binary-tree/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Level Order Traversal of Binary Tree
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, binary-tree, bfs
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/247-valid-binary-search-tree/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Valid Binary Search Tree
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, binary-search-tree, recursion
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/249-kth-smallest-integer-in-bst/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Kth Smallest Integer in BST
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, binary-search-tree, recursion
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/251-binary-tree-from-preorder-and-inorder-traversal/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Binary Tree from Preorder and Inorder Traversal
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, binary-tree, recursion
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/253-binary-tree-maximum-path-sum/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: hard
2 | title: Binary Tree Maximum Path Sum
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, binary-tree, recursion
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/255-serialize-and-deserialize-binary-tree/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: hard
2 | title: Serialize and Deserialize Binary Tree
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, binary-tree, serialization
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/257-find-median-in-a-data-stream/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: hard
2 | title: Find Median in a Data Stream
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, heap, data-stream
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/259-combination-target-sum/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Combination Target Sum
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, backtracking, recursion
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/261-search-for-word/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Search for Word
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, backtracking, matrix
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/263-implement-prefix-tree-trie/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Implement Prefix Tree (Trie)
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, trie, data-structure
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/265-design-word-search-data-structure/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Design Word Search Data Structure
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, trie, data-structure
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/267-search-for-word-ii/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: hard
2 | title: Search for Word II
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, trie, backtracking, matrix
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/269-count-number-of-islands/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Count Number of Islands
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, matrix, dfs
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/271-clone-graph/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Clone Graph
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, graph, dfs
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/273-pacific-atlantic-water-flow/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Pacific Atlantic Water Flow
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, matrix, dfs
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/275-course-schedule/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Course Schedule
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, graph, topological-sort
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/277-valid-tree/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Valid Tree
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, graph, union-find
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/279-count-connected-components/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Count Connected Components
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, graph, union-find
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/281-foreign-dictionary/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: hard
2 | title: Foreign Dictionary
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, graph, topological-sort
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/283-climbing-stairs/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: Climbing Stairs
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, dynamic-programming
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/285-house-robber/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: House Robber
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, dynamic-programming
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/287-house-robber-ii/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: House Robber II
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, dynamic-programming
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/289-longest-palindromic-substring/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Longest Palindromic Substring
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, dynamic-programming, string
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/291-palindromic-substrings/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Palindromic Substrings
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, dynamic-programming, string
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/293-decode-ways/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Decode Ways
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, dynamic-programming, string
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/295-coin-change/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Coin Change
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, dynamic-programming
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/297-maximum-product-subarray/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Maximum Product Subarray
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, dynamic-programming, array
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/299-word-break/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Word Break
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, dynamic-programming, string
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/3-use-hover/info.yml:
--------------------------------------------------------------------------------
1 | title: useHover
2 |
3 | author:
4 | name: Pawan Kumar
5 | email: pawankumar2901@gmail.com
6 | github: jsartisan
7 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
8 |
9 | tags: react, event listeners, hooks
10 |
11 | difficulty: hard
12 | published_date: '2024-02-21'
13 |
--------------------------------------------------------------------------------
/challenges/3-use-hover/template.react.md:
--------------------------------------------------------------------------------
1 | ```js App.jsx
2 | import { useHover } from "./useHover";
3 |
4 | function App() {
5 | const { hovered, ref } = useHover();
6 |
7 | return {hovered ? "I am hovered" : "Put mouse over me please"}
;
8 | }
9 |
10 | export default App;
11 | ```
12 |
13 | ```js useHover.js active
14 | import { useCallback, useEffect, useRef, useState } from "react";
15 |
16 | export function useHover() {
17 |
18 | }
19 | ```
20 |
--------------------------------------------------------------------------------
/challenges/301-longest-increasing-subsequence/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Longest Increasing Subsequence
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, dynamic-programming, array
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/303-count-paths/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Count Paths
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, dynamic-programming, matrix
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/305-longest-common-subsequence/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Longest Common Subsequence
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, dynamic-programming, string
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/307-maximum-subarray/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Maximum Subarray
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, dynamic-programming, array
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/309-jump-game/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Jump Game
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, dynamic-programming, array, greedy
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/311-insert-new-interval/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Insert New Interval
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, intervals
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/313-merge-intervals/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Merge Intervals
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, intervals
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/315-non-overlapping-intervals/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Non-overlapping Intervals
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, intervals, greedy
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/317-meeting-schedule/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: Meeting Schedule
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, intervals
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/319-meeting-schedule-ii/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Meeting Schedule II
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, intervals, greedy
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/32-instanceofclass/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: InstanceOfClass
3 | template: javascript
4 | tags: javascript
5 | author:
6 | github: jsartisan
7 | name: Pawan Kumar
8 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
9 | published_date: '2024-03-12'
10 |
11 |
--------------------------------------------------------------------------------
/challenges/321-rotate-matrix/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Rotate Matrix
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, matrix
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/323-spiral-matrix/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Spiral Matrix
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, matrix
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/325-set-zeroes-in-matrix/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Set Zeroes in Matrix
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, matrix
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/327-number-of-one-bits/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: Number of One Bits
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, bit-manipulation
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/329-counting-bits/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: Counting Bits
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, bit-manipulation, dynamic-programming
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/331-reverse-bits/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: Reverse Bits
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, bit-manipulation
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/333-missing-number/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: Missing Number
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, bit-manipulation, math
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/335-sum-of-two-integers/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Sum of Two Integers
3 | type: question
4 | template: typescript
5 | tags: javascript, blind75, bit-manipulation
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-02'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/340-escape-the-overflow-hidden/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Escape the overflow hidden
3 | type: question
4 | template: static
5 | tags: css
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-11-11'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/346-promise-order/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: Promise Order
3 | type: quiz
4 | tags: javascript, promises
5 | author:
6 | github: jsartisan
7 | name: Pawan Kumar
8 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
9 | published_date: '2024-12-26'
10 |
11 |
--------------------------------------------------------------------------------
/challenges/348-promise-resolution-order/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: Promise Resolution Order
3 | type: quiz
4 | tags: javascript, promises
5 | author:
6 | github: jsartisan
7 | name: Pawan Kumar
8 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
9 | published_date: '2024-12-26'
10 |
11 |
--------------------------------------------------------------------------------
/challenges/348-promise-resolution-order/solution.md:
--------------------------------------------------------------------------------
1 | The code will output:
2 | ```
3 | 1
4 | ```
5 |
6 | This is because:
7 | 1. In a Promise, only the first `resolve()` or `reject()` call takes effect
8 | 2. Once a Promise is settled (either resolved or rejected), it cannot change its state
9 | 3. In this case, `resolve(1)` is called first, so the subsequent `resolve(2)` and `reject('error')` are ignored
10 | 4. The `.then()` handler receives the value from the first `resolve(1)` call and logs it
11 |
--------------------------------------------------------------------------------
/challenges/35-promise-all/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: hard
2 | title: Promise.all
3 | template: javascript
4 | tags: javascript
5 | author:
6 | github: jsartisan
7 | name: Pawan Kumar
8 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
9 | published_date: '2024-03-15'
10 |
11 |
--------------------------------------------------------------------------------
/challenges/350-promise-chain-output/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: Promise Chain Output
3 | type: quiz
4 | tags: javascript, promises
5 | author:
6 | github: jsartisan
7 | name: Pawan Kumar
8 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
9 | published_date: '2024-12-26'
10 |
11 |
--------------------------------------------------------------------------------
/challenges/350-promise-chain-output/solution.md:
--------------------------------------------------------------------------------
1 | The output will be: `6`
2 |
3 | 1. `Promise.resolve(1)` → Initial value is `1`
4 | 2. `.then(() => 2)` → Returns `2`
5 | 3. `.then(3)` → Ignored because `3` is not a function, passes previous value `2`
6 | 4. `.then((value) => value * 3)` → `2 * 3 = 6`
7 | 5. `.then(Promise.resolve(4))` → Ignored because it's not a function, passes previous value `6`
8 | 6. `.then(console.log)` → Prints `6`
9 |
10 | **Key points**:
11 | - If `.then()` receives a non-function (like `3` or `Promise.resolve(4)`), it ignores that handler and passes the previous value through
12 | - Only function handlers are executed in the chain
13 |
--------------------------------------------------------------------------------
/challenges/352-promise-chain-output-2/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: Promise Chain Output 2
3 | type: quiz
4 | tags: javascript, promises
5 | author:
6 | github: jsartisan
7 | name: Pawan Kumar
8 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
9 | published_date: '2024-12-26'
10 |
11 |
--------------------------------------------------------------------------------
/challenges/352-promise-chain-output-2/solution.md:
--------------------------------------------------------------------------------
1 | ```
2 | 1
3 | 2
4 | undefined
5 | 3
6 | undefined
7 | 4
8 | undefined
9 | undefined
10 | ```
11 |
12 | Here's why:
13 | 1. `1` - First promise resolves with 1
14 | 2. `2` - Second .then gets 1+1
15 | 3. `undefined` - Third .then gets undefined (since previous .then had no return)
16 | 4. `3` - From the nested Promise.resolve(3)
17 | 5. `undefined` - Next .then gets undefined (nested promise had no return)
18 | 6. `4` - From Promise.reject(4) caught in catch
19 | 7. `undefined` - From finally (finally always receives undefined)
20 | 8. `undefined` - Last .then gets undefined (finally's return value is ignored)
21 |
22 | Key points:
23 | - If a .then doesn't return anything, the next .then receives `undefined`
24 | - finally() always receives `undefined` and its return value is ignored
25 | - The chain continues after catch() with undefined
26 |
--------------------------------------------------------------------------------
/challenges/37-promise-race/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: hard
2 | title: Promise.race
3 | template: javascript
4 | tags: javascript
5 | author:
6 | github: ashutoshbarthwal
7 | name: Ashutosh Barthwal
8 | avatar_url: https://avatars.githubusercontent.com/u/31532772?v=4
9 | published_date: '2024-03-15'
10 |
11 |
--------------------------------------------------------------------------------
/challenges/4-use-focus-trap/info.yml:
--------------------------------------------------------------------------------
1 | title: useFocusTrap
2 |
3 | author:
4 | name: Pawan Kumar
5 | email: pawankumar2901@gmail.com
6 | github: jsartisan
7 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
8 |
9 | tags: react, event listeners, hooks
10 |
11 | category: react
12 |
13 | difficulty: hard
14 |
--------------------------------------------------------------------------------
/challenges/4-use-focus-trap/template.react.md:
--------------------------------------------------------------------------------
1 | ```js App.jsx
2 | import { useFocusTrap } from "./useFocusTrap";
3 |
4 | function App() {
5 | const focusTrapRef = useFocusTrap();
6 |
7 | return (
8 |
9 |
10 |
11 | );
12 | }
13 |
14 | export default App;
15 | ```
16 |
17 | ```js useFocusTrap.js active
18 | export function useFocusTrap() {
19 |
20 | }
21 | ```
22 |
--------------------------------------------------------------------------------
/challenges/40-layout-1/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: Layout 1
3 | template: vanilla
4 | tags: css, layout
5 | author:
6 | github: jsartisan
7 | name: Pawan Kumar
8 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
9 | published_date: '2024-03-16'
10 |
11 |
--------------------------------------------------------------------------------
/challenges/40-layout-1/template.vanilla.md:
--------------------------------------------------------------------------------
1 | ```css styles.css active
2 | .container {
3 |
4 | }
5 |
6 | .item {
7 | background: #e1e1e1;
8 | height: 100px;
9 | }
10 | ```
11 |
12 | ```js index.js hidden
13 | import "./styles.css";
14 |
15 | ```
16 |
17 | ```html index.html
18 |
19 |
20 |
21 |
22 | Parcel Sandbox
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 | ```
39 |
40 |
41 |
--------------------------------------------------------------------------------
/challenges/43-promise-any/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: hard
2 | title: Promise.any
3 | template: javascript
4 | tags: javascript, promise
5 | author:
6 | github: nitish8899
7 | name: Nitish Rajput
8 | avatar_url: https://avatars.githubusercontent.com/u/161798180?v=4
9 | published_date: '2024-03-18'
10 |
11 |
--------------------------------------------------------------------------------
/challenges/45-specificity/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: Specificity
3 | tags: css
4 | type: quiz
5 | author:
6 | github: jsartisan
7 | name: Pawan Kumar
8 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
9 | published_date: '2024-03-20'
10 |
11 |
--------------------------------------------------------------------------------
/challenges/45-specificity/solution.md:
--------------------------------------------------------------------------------
1 | To delve deeper, both the CSS rules assigning the colors purple and red (`p.inner` & `.outer p`)share a specificity of 0–0–0–1–1. This is because they each incorporate one Class Selector and one Type Selector.
2 |
3 | Conversely, the rule assigning the color blue holds a specificity of 0–0–0–1–0 (`.inner` & `p`), involving only one Class Selector. Similarly, the rule setting the color green possesses a specificity of 0–0–0–0–1, utilizing solely one Type Selector.
4 |
5 | Hence, the rules with the highest specificity values are those assigning the colors purple and red.
6 |
7 | However, what if two CSS rules boast the same specificity value? How do we determine which one takes precedence?
8 |
9 | This is where the **Cascading** in Cascading Style Sheets (CSS) becomes relevant. Essentially, the rule that appears last (at the bottom) will be applied. In this scenario, it would be the rule assigning the color red.
10 |
--------------------------------------------------------------------------------
/challenges/47-checkbox/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Checkbox
3 | template: vanilla
4 | tags: css, design-system, html
5 | author:
6 | github: jsartisan
7 | name: Pawan Kumar
8 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
9 | published_date: '2024-03-26'
10 |
11 |
--------------------------------------------------------------------------------
/challenges/47-checkbox/template.vanilla.md:
--------------------------------------------------------------------------------
1 | ```css styles.css
2 | body {
3 | font-family: sans-serif;
4 | }
5 |
6 | h1 {
7 | font-size: 1.5rem;
8 | }
9 | ```
10 |
11 | ```js index.js
12 | import "./styles.css";
13 |
14 | ```
15 |
16 | ```html index.html
17 |
18 |
19 |
20 |
21 | Parcel Sandbox
22 |
23 |
24 |
25 |
26 |
30 |
31 |
32 |
33 | ```
34 |
35 |
36 |
--------------------------------------------------------------------------------
/challenges/49-holy-grail/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: Holy Grail
3 | type: question
4 | template: vanilla
5 | tags: css, layout
6 | author:
7 | github: nitish8899
8 | name: Nitish Rajput
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-04-15'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/5-fluid-typography/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Fluid Typography
3 | template: vanilla
4 | tags: css, typography
5 | author:
6 | github: jsartisan
7 | name: Pawan Kumar
8 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
9 | published_date: 2024-01-10
10 |
11 |
--------------------------------------------------------------------------------
/challenges/5-fluid-typography/template.vanilla.md:
--------------------------------------------------------------------------------
1 | ```css styles.css active
2 | body {
3 | font-family: sans-serif;
4 | }
5 |
6 | :root {
7 | --minVw: 320px;
8 | --maxVw: 720px;
9 | --minSize: 16px;
10 | --maxSize: 32px;
11 | }
12 |
13 | h1 {
14 | font-size: /* write your answer here */;
15 | }
16 | ```
17 |
18 | ```js index.js
19 | import "./styles.css";
20 | ```
21 |
22 | ```html index.html
23 |
24 |
25 |
26 |
27 | Parcel Sandbox
28 |
29 |
30 |
31 |
32 | Hello World
33 |
34 |
36 |
37 |
38 |
39 | ```
40 |
41 | ```json package.json
42 | {
43 | "dependencies": {},
44 | "main": "/index.js",
45 | "devDependencies": {}
46 | }
47 | ```
48 |
49 |
50 |
--------------------------------------------------------------------------------
/challenges/55-memo/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: memo
3 | type: question
4 | template: javascript
5 | tags: javascript, performance
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-04-27'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/55-memo/template.javascript.md:
--------------------------------------------------------------------------------
1 | ```js index.js
2 | export function memo(func) {
3 |
4 | }
5 |
6 | ```
7 |
8 | ```js index.test.js
9 | import { memo } from './index';
10 |
11 | describe('memo function', () => {
12 | it('should memoize function calls', () => {
13 | const expensiveFunction = jest.fn((x, y) => x + y);
14 |
15 | const memoizedFunction = memo(expensiveFunction);
16 |
17 | memoizedFunction(2, 3);
18 | memoizedFunction(2, 3);
19 | memoizedFunction(2, 3);
20 |
21 | // Ensure the expensive function is called only once
22 | expect(expensiveFunction).toHaveBeenCalledTimes(1);
23 | });
24 |
25 | it('should memoize function calls with different arguments', () => {
26 | const expensiveFunction = jest.fn((x, y) => x + y);
27 |
28 | const memoizedFunction = memo(expensiveFunction);
29 |
30 | memoizedFunction(2, 3);
31 | memoizedFunction(3, 4);
32 | memoizedFunction(2, 3);
33 | memoizedFunction(3, 4);
34 |
35 | expect(expensiveFunction).toHaveBeenCalledTimes(2);
36 | });
37 | });
38 | ```
39 |
40 |
41 |
--------------------------------------------------------------------------------
/challenges/58-event-emitter/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Event Emitter
3 | type: question
4 | template: javascript
5 | tags: javascript, events
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-05-14'
11 |
12 |
--------------------------------------------------------------------------------
/challenges/6-debounce/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: hard
2 | title: Debounce
3 | template: tests
4 | tags: javascript, closure
5 | author:
6 | github: jsartisan
7 | name: Pawan Kumar
8 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
9 | published_date: 2024-01-14
10 |
11 |
--------------------------------------------------------------------------------
/challenges/61-logical-operators/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: Logical Operators
3 | type: quiz
4 | tags: javascript, logical operators
5 | author:
6 | github: jsartisan
7 | name: Pawan Kumar
8 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
9 | published_date: '2024-05-18'
10 | discussionNo: 65
11 | mcq:
12 | options:
13 | - |
14 | "&&" and "||"
15 | - |
16 | "==" and "!="
17 | - |
18 | "===" and "!=="
19 | - |
20 | "++" and "--"
21 | right_answer: 2
22 |
--------------------------------------------------------------------------------
/challenges/66-this/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: this
3 | type: quiz
4 | tags: javascript, objects
5 | author:
6 | github: jsartisan
7 | name: Pawan Kumar
8 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
9 | published_date: '2024-06-03'
10 | discussionNo: 68
11 |
12 |
--------------------------------------------------------------------------------
/challenges/69-two-functions-one-object/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: Two functions - one object
3 | type: question
4 | template: javascript
5 | tags: javascript, objects
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-06-04'
11 | discussionNo: 71
12 |
13 |
--------------------------------------------------------------------------------
/challenges/69-two-functions-one-object/template.javascript.md:
--------------------------------------------------------------------------------
1 | ```js index.js
2 | export function A() {
3 | // your code here
4 | }
5 |
6 | export function B() {
7 | // your code here
8 | }
9 | ```
10 |
11 | ```js index.test.js
12 | import { A, B } from './index';
13 |
14 | describe('Constructor Functions A and B', () => {
15 | test('new A() should equal new B()', () => {
16 | let a = new A();
17 | let b = new B();
18 |
19 | expect(a).toBe(b);
20 | });
21 | });
22 | ```
23 |
24 |
25 |
--------------------------------------------------------------------------------
/challenges/7-promise-order/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | importance: high
3 | title: Promise Order
4 | tags: javascript, promise, event loop
5 | author:
6 | github: jsartisan
7 | name: Pawan Kumar
8 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
9 | published_date: 2024-02-02
10 | type: quiz
11 |
12 |
--------------------------------------------------------------------------------
/challenges/74-array-prototype-filter/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: Array.prototype.filter
3 | type: question
4 | template: javascript
5 | tags: javascript
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-06-17'
11 | discussionNo: 76
12 |
13 |
--------------------------------------------------------------------------------
/challenges/78-array-prototype-map/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: Array.prototype.map
3 | type: question
4 | template: javascript
5 | tags: javascript
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-06-17'
11 | discussionNo: 80
12 |
13 |
--------------------------------------------------------------------------------
/challenges/8-closure/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: Closure
3 | tags: closure, javascript
4 | author:
5 | github: jsartisan
6 | name: Pawan Kumar
7 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
8 | published_date: '2024-02-18'
9 | type: quiz
10 |
11 |
--------------------------------------------------------------------------------
/challenges/8-closure/solution.md:
--------------------------------------------------------------------------------
1 | The answer is `3 3 3` and `0 1 2`
2 |
3 | ### Explaination
4 | Due to the event queue mechanism in JavaScript, the setTimeout callback function is executed after the loop completes its iterations. In the first loop, the variable i was declared with the var keyword, making it global in scope. Consequently, as the loop iterated and incremented `i` using the unary operator ++, the value of `i` became 3 by the time the setTimeout callback function was called.
5 |
6 | In contrast, the second loop declared the variable i with the let keyword. Variables declared with let (and const) are block-scoped, meaning their scope is limited to the block in which they are defined (a block is delineated by {}). Therefore, with each iteration of the loop, `i` obtains a new value, and each value is confined within the loop's scope.
7 |
--------------------------------------------------------------------------------
/challenges/82-array-prototype-reduce/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: medium
2 | title: Array.prototype.reduce
3 | type: question
4 | template: javascript
5 | tags: javascript
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-06-18'
11 | discussionNo: 84
12 |
13 |
--------------------------------------------------------------------------------
/challenges/86-chunk/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: Chunk
3 | type: question
4 | template: javascript
5 | tags: javascript
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-06-18'
11 | discussionNo: 88
12 |
13 |
--------------------------------------------------------------------------------
/challenges/91-stack/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: Stack
3 | type: question
4 | template: javascript
5 | tags: javascript
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-06-24'
11 | discussionNo: 93
12 |
13 |
--------------------------------------------------------------------------------
/challenges/95-queue/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: Queue
3 | type: question
4 | template: javascript
5 | tags: javascript
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-06-26'
11 | discussionNo: 97
12 |
13 |
--------------------------------------------------------------------------------
/challenges/99-closure-2/info.yml:
--------------------------------------------------------------------------------
1 | difficulty: easy
2 | title: Closure 2
3 | type: question
4 | template: javascript
5 | tags: javascript, closure
6 | author:
7 | github: jsartisan
8 | name: Pawan Kumar
9 | avatar_url: https://avatars.githubusercontent.com/u/6636360?v=4
10 | published_date: '2024-07-01'
11 | discussionNo: 101
12 |
13 |
--------------------------------------------------------------------------------
/locales/en.json:
--------------------------------------------------------------------------------
1 | {
2 | "badge.back": "Back",
3 | "badge.checkout-solutions": "Check out Solutions",
4 | "badge.share-your-solutions": "Share your Solutions",
5 | "badge.take-the-challenge": "Take the Challenge",
6 | "badge.preview-playground": "Preview in Playground",
7 | "difficulty.easy": "easy",
8 | "difficulty.extreme": "extreme",
9 | "difficulty.hard": "hard",
10 | "difficulty.medium": "medium",
11 | "difficulty.warm": "warm-up",
12 | "display": "English",
13 | "divider.code-start": "Your Code Here",
14 | "divider.further-steps": "Further Steps",
15 | "divider.test-cases": "Test Cases",
16 | "link.checkout-solutions": "View solutions: ",
17 | "link.more-challenges": "More Challenges: ",
18 | "link.share-solutions": "Share your solutions: ",
19 | "link.view-on-github": "View on GitHub: ",
20 | "readme.related-challenges": "Related Challenges",
21 | "readme.google-translated": "Translated by Google, open a PR to help improving the translation.",
22 | "title.question": "Question"
23 | }
24 |
--------------------------------------------------------------------------------
/packages/backend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@frontend-challenges/backend",
3 | "version": "0.1.0",
4 | "private": true,
5 | "author": "Pawan Kumar ",
6 | "license": "MIT",
7 | "repository": "https://github.com/jsartisan/frontend-challenges.git",
8 | "main": "src/index.ts",
9 | "dependencies": {
10 | "@/shared": "workspace:*",
11 | "@types/fs-extra": "^11.0.4",
12 | "fast-glob": "^3.3.2",
13 | "fs-extra": "^11.2.0",
14 | "gray-matter": "^4.0.3",
15 | "js-yaml": "^4.1.0",
16 | "mdast": "^3.0.0",
17 | "octokit": "^3.1.2",
18 | "remark-parse": "^11.0.0"
19 | },
20 | "devDependencies": {
21 | "@types/js-yaml": "^4.0.9",
22 | "@types/mdast": "^4.0.4"
23 | }
24 | }
--------------------------------------------------------------------------------
/packages/backend/src/db/blogs.ts:
--------------------------------------------------------------------------------
1 | import fs from "fs";
2 | import path from "path";
3 | import glob from "fast-glob";
4 | import matter from "gray-matter";
5 | import { Blog, CONTENT_PATH } from "@/shared";
6 |
7 | export const getAllBlogs = (): Blog[] => {
8 | const PATH = path.join(CONTENT_PATH, "blog");
9 | const paths = glob.sync(`${PATH}/**/*.md`);
10 |
11 | return paths
12 | .map((filePath) => {
13 | const source = fs.readFileSync(path.join(filePath), "utf8");
14 | const { data } = matter(source);
15 |
16 | return {
17 | ...data,
18 | slug: filePath.replace(`${PATH}/`, "").replace("/index.md", ""),
19 | path: filePath.replace(`${CONTENT_PATH.replace("./", "")}/`, "").replace("/index.md", ""),
20 | };
21 | })
22 |
23 | .sort((a: any, b: any) => Number(new Date(b.publishedAt)) - Number(new Date(a.publishedAt))) as Blog[];
24 | };
25 |
26 | export const getBlogBySlug = async (slug: string) => {
27 | const source = fs.readFileSync(path.join(CONTENT_PATH, "blog", `${slug}/index.md`), "utf8");
28 |
29 | return source;
30 | };
31 |
--------------------------------------------------------------------------------
/packages/backend/src/db/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./challenges";
2 | export * from "./templates";
3 | export * from "./locales";
4 | export * from "./fs";
5 | export * from "./roadmaps";
6 | export * from "./blogs";
7 |
--------------------------------------------------------------------------------
/packages/backend/src/db/locales.ts:
--------------------------------------------------------------------------------
1 | import path from "path";
2 | import { pipe } from "@/shared";
3 | import { DEFAULT_LOCALE, SUPPORTED_LOCALES } from "@/shared";
4 |
5 | import { loadFile } from "./fs";
6 |
7 | export async function getLocaleVariations(filepath: string, fns: ((s: string) => T)[]) {
8 | const { ext, dir, name } = path.parse(filepath);
9 | const data: Record = {};
10 |
11 | for (const locale of SUPPORTED_LOCALES) {
12 | const file = pipe((await loadFile(path.join(dir, `${name}.${locale}${ext}`))) || "", ...fns);
13 |
14 | if (file) data[locale] = file;
15 | }
16 |
17 | if (!data[DEFAULT_LOCALE]) {
18 | // default version
19 | const file = pipe((await loadFile(filepath)) || "", ...fns);
20 | if (file) data[DEFAULT_LOCALE] = file;
21 | }
22 |
23 | return data;
24 | }
25 |
--------------------------------------------------------------------------------
/packages/backend/src/db/templates.ts:
--------------------------------------------------------------------------------
1 | import path from "path";
2 | import { unified } from "unified";
3 | import remarkParse from "remark-parse";
4 |
5 | import { loadFile } from "./fs";
6 | import { CodeFile, SupportedTemplates } from "@/shared";
7 | import { createFileMap, SUPPORTED_TEMPLATES } from "@/shared";
8 |
9 | /**
10 | * get code files group by template (vanilla, react, vue, etc)
11 | *
12 | * @param filepath
13 | * @returns
14 | */
15 | export async function getCodeFilesByTemplate(filepath: string) {
16 | const { ext, dir, name } = path.parse(filepath);
17 | const data = {} as Record>;
18 |
19 | for (const template of SUPPORTED_TEMPLATES) {
20 | const file = await loadFile(path.join(dir, `${name}.${template}${ext}`));
21 |
22 | if (file) {
23 | const result = await unified().use(remarkParse).parse(file);
24 |
25 | data[template] = createFileMap(result);
26 | }
27 | }
28 |
29 | return data;
30 | }
31 |
--------------------------------------------------------------------------------
/packages/backend/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./db";
2 | export * from "./utils";
3 |
--------------------------------------------------------------------------------
/packages/backend/src/utils/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./readme";
2 |
--------------------------------------------------------------------------------
/packages/scripts/actions/loader.ts:
--------------------------------------------------------------------------------
1 | import * as io from "@actions/io";
2 | import * as core from "@actions/core";
3 | import { context, getOctokit } from "@actions/github";
4 |
5 | process.on("unhandledRejection", handleError);
6 | main().catch(handleError);
7 |
8 | async function main(): Promise {
9 | const token = process.argv[2];
10 | const fnName = process.argv[3];
11 | const github = getOctokit(token);
12 |
13 | // eslint-disable-next-line @typescript-eslint/no-var-requires
14 | const fn = require(`./${fnName}.ts`);
15 | fn.default(github, context, core, io);
16 | }
17 |
18 | function handleError(err: any): void {
19 | console.error(err);
20 | core.setFailed(`Unhandled error: ${err}`);
21 | process.exit(1);
22 | }
23 |
--------------------------------------------------------------------------------
/packages/scripts/templates/template-javascript/index.js:
--------------------------------------------------------------------------------
1 | export const add = (a, b) => a + b;
2 |
--------------------------------------------------------------------------------
/packages/scripts/templates/template-javascript/index.test.js:
--------------------------------------------------------------------------------
1 | import { add } from "./index";
2 |
3 | describe("add", () => {
4 | it("adds two numbers", () => {
5 | expect(add(1, 2)).toBe(3);
6 | });
7 | });
8 |
--------------------------------------------------------------------------------
/packages/scripts/templates/template-react/App.jsx:
--------------------------------------------------------------------------------
1 | import "./styles.css";
2 |
3 | function App() {
4 | return Hello World
;
5 | }
6 |
7 | export default App;
8 |
--------------------------------------------------------------------------------
/packages/scripts/templates/template-react/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite + React
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/packages/scripts/templates/template-react/index.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom/client";
3 |
4 | import App from "./App";
5 | import "./styles.css";
6 |
7 | ReactDOM.createRoot(document.getElementById("root")).render(
8 |
9 |
10 | ,
11 | );
12 |
--------------------------------------------------------------------------------
/packages/scripts/templates/template-react/styles.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/frontend-challenges/81bd0e5a3b27fc84925a7ad431f12c973e81c9c6/packages/scripts/templates/template-react/styles.css
--------------------------------------------------------------------------------
/packages/scripts/templates/template-vanilla/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite + React
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/packages/scripts/templates/template-vanilla/index.js:
--------------------------------------------------------------------------------
1 | console.log("Hello from template-vanilla");
2 |
--------------------------------------------------------------------------------
/packages/scripts/templates/template-vanilla/styles.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/frontend-challenges/81bd0e5a3b27fc84925a7ad431f12c973e81c9c6/packages/scripts/templates/template-vanilla/styles.css
--------------------------------------------------------------------------------
/packages/scripts/templates/template-vite/.eslintrc.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | env: { browser: true, es2020: true, jest: true },
4 | extends: [
5 | "eslint:recommended",
6 | "plugin:react/recommended",
7 | "plugin:react/jsx-runtime",
8 | "plugin:react-hooks/recommended",
9 | ],
10 | ignorePatterns: ["dist", ".eslintrc.cjs"],
11 | parserOptions: { ecmaVersion: "latest", sourceType: "module" },
12 | settings: { react: { version: "18.2" } },
13 | plugins: ["react-refresh"],
14 | rules: {
15 | "react-refresh/only-export-components": ["warn", { allowConstantExport: true }],
16 | },
17 | };
18 |
--------------------------------------------------------------------------------
/packages/scripts/templates/template-vite/README.md:
--------------------------------------------------------------------------------
1 | # React + Vite
2 |
3 | This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
4 |
5 | Currently, two official plugins are available:
6 |
7 | - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
8 | - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
9 |
--------------------------------------------------------------------------------
/packages/scripts/templates/template-vite/_gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/packages/scripts/templates/template-vite/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Document
7 |
8 |
9 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/packages/scripts/templates/template-vite/jest.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "preset": "ts-jest",
3 | "testEnvironment": "jsdom",
4 | "transform": {
5 | "^.+\\.(js|ts)?$": "ts-jest"
6 | },
7 | "transformIgnorePatterns": ["/node_modules/"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/scripts/templates/template-vite/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from "vite";
2 | import react from "@vitejs/plugin-react";
3 | import vue from "@vitejs/plugin-vue";
4 | import { svelte } from "@sveltejs/vite-plugin-svelte";
5 |
6 | // https://vitejs.dev/config/
7 | export default defineConfig({
8 | plugins: [react(), vue(), svelte()],
9 | });
10 |
--------------------------------------------------------------------------------
/packages/scripts/types.ts:
--------------------------------------------------------------------------------
1 | import type IO from "@actions/io";
2 | import type Core from "@actions/core";
3 | import type { context, getOctokit } from "@actions/github";
4 |
5 | export type Context = typeof context;
6 | export type Github = ReturnType;
7 | export type Action = (github: Github, context: Context, core: typeof Core, io: typeof IO) => Promise;
8 |
--------------------------------------------------------------------------------
/packages/scripts/utils/formatToCode.ts:
--------------------------------------------------------------------------------
1 | import { translate } from "@/shared";
2 | import { DEFAULT_LOCALE } from "@/shared";
3 | import { Question, SupportedLocales } from "@/shared";
4 |
5 | import { toCommentBlock } from "./toCommentBlock";
6 | import { toInfoHeader } from "./toInfoHeader";
7 | import { toLinks } from "./toLinks";
8 | import { toDivider } from "./toDivider";
9 | import { toFooter } from "./toFooter";
10 |
11 | export const formatToCode = (quiz: Question, locale: SupportedLocales) => {
12 | return `${
13 | toCommentBlock(
14 | toInfoHeader(quiz, locale) + (quiz.readme[locale] || quiz.readme[DEFAULT_LOCALE]) + toLinks(quiz, locale),
15 | ) + toDivider(translate(locale, "divider.code-start"))
16 | }\n${toDivider(translate(locale, "divider.further-steps"))}${toCommentBlock(toFooter(quiz, locale))}`;
17 | };
18 |
--------------------------------------------------------------------------------
/packages/scripts/utils/index.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/frontend-challenges/81bd0e5a3b27fc84925a7ad431f12c973e81c9c6/packages/scripts/utils/index.ts
--------------------------------------------------------------------------------
/packages/scripts/utils/locales.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/frontend-challenges/81bd0e5a3b27fc84925a7ad431f12c973e81c9c6/packages/scripts/utils/locales.ts
--------------------------------------------------------------------------------
/packages/scripts/utils/toCommentBlock.ts:
--------------------------------------------------------------------------------
1 | export const toCommentBlock = function (text: string) {
2 | return `/*\n${text
3 | .trim()
4 | .split("\n")
5 | .map((i) => (i.trim() ? ` ${i}`.trimEnd() : ""))
6 | .join("\n")}\n*/\n`;
7 | };
8 |
--------------------------------------------------------------------------------
/packages/scripts/utils/toDivider.ts:
--------------------------------------------------------------------------------
1 | export const toDivider = function (text: string) {
2 | return `\n/* _____________ ${text} _____________ */\n`;
3 | };
4 |
--------------------------------------------------------------------------------
/packages/scripts/utils/toFooter.ts:
--------------------------------------------------------------------------------
1 | import { translate } from "@/shared";
2 | import { Question, SupportedLocales } from "@/shared";
3 | import { getShareAnswerURL, getSolutionsURL, getRepoREADMEUrl } from "@/shared";
4 |
5 | export const toFooter = function (quiz: Question, locale: SupportedLocales) {
6 | return (
7 | "\n\n" +
8 | `> ${translate(locale, "link.share-solutions")}${getShareAnswerURL({ challenge: quiz, locale })}\n` +
9 | `> ${translate(locale, "link.checkout-solutions")}${getSolutionsURL(quiz.no)}\n` +
10 | `> ${translate(locale, "link.more-challenges")}${getRepoREADMEUrl(locale)}\n`
11 | );
12 | };
13 |
--------------------------------------------------------------------------------
/packages/scripts/utils/toInfoHeader.ts:
--------------------------------------------------------------------------------
1 | import { translate } from "@/shared";
2 | import { getChallengeInfoByLocale } from "@frontend-challenges/backend";
3 | import { Question, SupportedLocales } from "@/shared";
4 |
5 | export const toInfoHeader = function toInfoHeader(quiz: Question, locale: SupportedLocales) {
6 | const info = getChallengeInfoByLocale(quiz, locale);
7 |
8 | const author = `${info.author?.name} (@${info?.author?.github})`;
9 |
10 | return (
11 | `${quiz.no} - ${info.title || ""}\n` +
12 | "-------\n" +
13 | `by ${author} #${translate(locale, `difficulty.${quiz.difficulty}`)} ${
14 | info?.tags?.map((i) => `#${i}`).join(" ") || ""
15 | }\n\n` +
16 | `### ${translate(locale, "title.question")}\n\n`
17 | );
18 | };
19 |
--------------------------------------------------------------------------------
/packages/scripts/utils/toLinks.ts:
--------------------------------------------------------------------------------
1 | import { translate } from "@/shared";
2 | import { toReadmeShort } from "@/shared";
3 | import { Question, SupportedLocales } from "@/shared";
4 |
5 | export function toLinks(quiz: Question, locale: SupportedLocales) {
6 | return "\n\n" + `> ${translate(locale, "link.view-on-github")}${toReadmeShort(quiz.no, locale)}`;
7 | }
8 |
--------------------------------------------------------------------------------
/packages/shared/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@/shared",
3 | "version": "0.1.0",
4 | "private": true,
5 | "author": "Pawan Kumar ",
6 | "license": "MIT",
7 | "repository": "https://github.com/jsartisan/frontend-challenges.git",
8 | "main": "src/index.ts",
9 | "dependencies": {
10 | "@types/fs-extra": "^11.0.4",
11 | "fast-glob": "^3.3.2",
12 | "fs-extra": "^11.2.0",
13 | "js-yaml": "^4.1.0",
14 | "mdast": "^3.0.0",
15 | "octokit": "^3.1.2",
16 | "remark-parse": "^11.0.0"
17 | },
18 | "devDependencies": {
19 | "@types/js-yaml": "^4.0.9",
20 | "@types/mdast": "^4.0.4"
21 | }
22 | }
--------------------------------------------------------------------------------
/packages/shared/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./constants";
2 | export * from "./types";
3 | export * from "./utils";
4 | export * from "./templates";
5 |
--------------------------------------------------------------------------------
/packages/shared/src/templates/common.ts:
--------------------------------------------------------------------------------
1 | export const commonFiles = {
2 | "/styles.css": {
3 | code: `body {
4 | font-family: sans-serif;
5 | }
6 |
7 | h1 {
8 | font-size: 1.5rem;
9 | }`,
10 | },
11 | };
12 |
--------------------------------------------------------------------------------
/packages/shared/src/templates/index.ts:
--------------------------------------------------------------------------------
1 | import { VUE_TEMPLATE } from "./vue";
2 | import { TESTS_TEMPLATE } from "./tests";
3 | import { REACT_TEMPLATE } from "./react";
4 | import { SVELTE_TEMPLATE } from "./svelte";
5 | import { STATIC_TEMPLATE } from "./static";
6 | import { VANILLA_TEMPLATE } from "./vanilla";
7 | import { TYPESCRIPT_TEMPLATE } from "./typescript";
8 |
9 | export const TEMPLATES = {
10 | static: STATIC_TEMPLATE,
11 | vanilla: VANILLA_TEMPLATE,
12 | typescript: TYPESCRIPT_TEMPLATE,
13 | javascript: TESTS_TEMPLATE,
14 | react: REACT_TEMPLATE,
15 | vue: VUE_TEMPLATE,
16 | svelte: SVELTE_TEMPLATE,
17 | };
18 |
--------------------------------------------------------------------------------
/packages/shared/src/templates/static.ts:
--------------------------------------------------------------------------------
1 | import { commonFiles } from "./common";
2 |
3 | export const STATIC_TEMPLATE = {
4 | files: {
5 | ...commonFiles,
6 | "/index.html": {
7 | code: `
8 |
9 |
10 |
11 | Parcel Sandbox
12 |
13 |
14 |
15 |
16 |
17 | Hello world
18 |
19 |
20 | `,
21 | },
22 | "/package.json": {
23 | code: JSON.stringify({
24 | dependencies: {},
25 | main: "/index.html",
26 | }),
27 | },
28 | },
29 | main: "/index.html",
30 | environment: "static",
31 | };
32 |
--------------------------------------------------------------------------------
/packages/shared/src/templates/tests.ts:
--------------------------------------------------------------------------------
1 | export const TESTS_TEMPLATE = {
2 | files: {
3 | "/index.js": {
4 | code: `export const add = (a, b) => a + b;`,
5 | },
6 | "/index.test.js": {
7 | code: `import { add } from './index';
8 |
9 | describe('add', () => {
10 | test('Commutative Law of Addition', () => {
11 | expect(add(1, 2)).toBe(add(2, 1));
12 | });
13 | });`,
14 | },
15 | "/package.json": {
16 | code: JSON.stringify({
17 | dependencies: {},
18 | main: "/index.js",
19 | devDependencies: {},
20 | }),
21 | },
22 | },
23 | main: "/index.test.js",
24 | environment: "parcel",
25 | mode: "tests",
26 | };
27 |
--------------------------------------------------------------------------------
/packages/shared/src/templates/typescript.ts:
--------------------------------------------------------------------------------
1 | export const TYPESCRIPT_TEMPLATE = {
2 | files: {
3 | "tsconfig.json": {
4 | hidden: true,
5 | code: `{
6 | "include": [
7 | "./**/*"
8 | ],
9 | "compilerOptions": {
10 | "strict": true,
11 | "esModuleInterop": true,
12 | "lib": [ "dom", "es2015" ],
13 | "jsx": "react-jsx",
14 | "types": [ "jest" ]
15 | }
16 | }`,
17 | },
18 | "/index.ts": {
19 | code: `export const add = (a: number, b: number) => a + b;`,
20 | },
21 | "/index.test.ts": {
22 | code: `import { add } from './index';
23 |
24 | describe('add', () => {
25 | test('Commutative Law of Addition', () => {
26 | expect(add(1, 2)).toBe(add(2, 1));
27 | });
28 | });`,
29 | },
30 | "/package.json": {
31 | hidden: true,
32 | code: JSON.stringify({
33 | dependencies: {},
34 | main: "/index.ts",
35 | devDependencies: { typescript: "^4.0.0" },
36 | }),
37 | },
38 | },
39 | main: "/index.test.ts",
40 | environment: "parcel",
41 | mode: "tests",
42 | };
43 |
--------------------------------------------------------------------------------
/packages/shared/src/templates/vanilla.ts:
--------------------------------------------------------------------------------
1 | import { commonFiles } from "./common";
2 |
3 | export const VANILLA_TEMPLATE = {
4 | files: {
5 | "/index.html": {
6 | active: true,
7 | code: `
8 |
9 |
10 | Parcel Sandbox
11 |
12 |
13 |
14 |
15 | Hello World
16 |
17 | `,
18 | },
19 | ...commonFiles,
20 | "/index.js": {
21 | code: `import "./styles.css";`,
22 | },
23 | "/package.json": {
24 | hidden: true,
25 | code: JSON.stringify({
26 | dependencies: {},
27 | main: "/index.js",
28 | devDependencies: {},
29 | }),
30 | },
31 | },
32 | main: "/index.js",
33 | environment: "parcel",
34 | };
35 |
--------------------------------------------------------------------------------
/packages/shared/src/types/env.d.ts:
--------------------------------------------------------------------------------
1 | declare namespace NodeJS {
2 | interface ProcessEnv {
3 | NEXT_PUBLIC_MIXPANEL_PROJECT_KEY: string;
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/packages/shared/src/utils/helpers.ts:
--------------------------------------------------------------------------------
1 | export function escapeHtml(unsafe: string) {
2 | return unsafe
3 | .replace(/&/g, "&")
4 | .replace(//g, ">")
6 | .replace(/"/g, """)
7 | .replace(/'/g, "'");
8 | }
9 |
10 | export const pipe = (value: any, ...fns: ((any) => any)[]) => fns.reduce((acc, fn) => fn(acc), value);
11 |
--------------------------------------------------------------------------------
/packages/shared/src/utils/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./questions";
2 | export * from "./helpers";
3 | export * from "./locales";
4 | export * from "./url";
5 | export * from "./template";
6 | export * from "./readme";
7 |
--------------------------------------------------------------------------------
/packages/shared/src/utils/locales.ts:
--------------------------------------------------------------------------------
1 | import { SupportedLocales } from "../types";
2 | import { DEFAULT_LOCALE, TRANSLATIONS } from "../constants";
3 |
4 | export function translate(locale: SupportedLocales, key: string): string {
5 | const result = (TRANSLATIONS[locale] && TRANSLATIONS[locale][key]) || TRANSLATIONS[DEFAULT_LOCALE][key];
6 |
7 | if (!result) throw new Error(`Missing message for key "${key}"`);
8 |
9 | return result;
10 | }
11 |
12 | export function getFileNameByLocale(name: string, locale: string, ext: string) {
13 | if (locale === DEFAULT_LOCALE) return `${name}.${ext}`;
14 |
15 | return `${name}.${locale}.${ext}`;
16 | }
17 |
--------------------------------------------------------------------------------
/packages/shared/src/utils/questions.ts:
--------------------------------------------------------------------------------
1 | import YAML from "js-yaml";
2 |
3 | import { QuestionMetaInfo } from "../types";
4 |
5 | /**
6 | * parses meta info from the yaml file
7 | *
8 | * @param s
9 | * @returns
10 | */
11 | export function parseMetaInfo(s: string): Partial | undefined {
12 | const object = YAML.load(s) as any;
13 | if (!object) return undefined;
14 |
15 | const arrayKeys = ["tags", "related"];
16 |
17 | for (const key of arrayKeys) {
18 | if (object[key]) {
19 | object[key] = (object[key] || "")
20 | .toString()
21 | .split(",")
22 | .map((i: string) => i.trim())
23 | .filter(Boolean);
24 | } else {
25 | object[key] = undefined;
26 | }
27 | }
28 |
29 | return object;
30 | }
31 |
--------------------------------------------------------------------------------
/packages/website/analytics/events.ts:
--------------------------------------------------------------------------------
1 | export const ANALYTICS_EVENTS = {
2 | CHALLENGE_VIEWED: "Challenge Viewed",
3 | CHALLENGE_COMPLETED: "Challenge Completed",
4 | } as const;
5 |
6 | export type AnalyticsEventName = (typeof ANALYTICS_EVENTS)[keyof typeof ANALYTICS_EVENTS];
7 |
8 | // Type-safe event properties
9 | export interface EventProperties {
10 | [ANALYTICS_EVENTS.CHALLENGE_VIEWED]: {
11 | challenge: number;
12 | title?: string;
13 | };
14 | }
15 |
--------------------------------------------------------------------------------
/packages/website/analytics/index.ts:
--------------------------------------------------------------------------------
1 | export { analytics } from "./setup";
2 |
--------------------------------------------------------------------------------
/packages/website/analytics/providers/mixpanel.ts:
--------------------------------------------------------------------------------
1 | import mixpanel from "mixpanel-browser";
2 | import { AnalyticsEvent, AnalyticsService } from "../types";
3 |
4 | export class MixpanelProvider implements AnalyticsService {
5 | constructor(token: string) {
6 | mixpanel.init(token);
7 | }
8 |
9 | track({ name, properties }: AnalyticsEvent) {
10 | mixpanel.track(name, properties);
11 | }
12 |
13 | identify(userId: string, traits?: Record) {
14 | mixpanel.identify(userId);
15 |
16 | if (traits) {
17 | mixpanel.people.set(traits);
18 | }
19 | }
20 |
21 | page(properties?: Record) {
22 | mixpanel.track("Page Viewed", properties);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/packages/website/analytics/setup.ts:
--------------------------------------------------------------------------------
1 | import { Analytics } from "./analytics";
2 | import { MixpanelProvider } from "./providers/mixpanel";
3 |
4 | export const analytics = new Analytics([new MixpanelProvider(process.env.NEXT_PUBLIC_MIXPANEL_PROJECT_KEY!)]);
5 |
--------------------------------------------------------------------------------
/packages/website/analytics/types.ts:
--------------------------------------------------------------------------------
1 | export interface AnalyticsEvent {
2 | name: string;
3 | properties?: Record;
4 | }
5 |
6 | export interface AnalyticsService {
7 | track(event: AnalyticsEvent): void;
8 | identify(userId: string, traits?: Record): void;
9 | page(properties?: Record): void;
10 | }
11 |
--------------------------------------------------------------------------------
/packages/website/app/blog/[slug]/client.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import * as React from "react";
4 |
5 | import { Card } from "../../../components/ui";
6 | import Footer from "../../../components/layout/Footer";
7 | import { Layout } from "../../../components/layout/Layout";
8 | import { MDXComponent } from "../../../components/common/MDXComponent";
9 |
10 | export default function Client(props: any) {
11 | const { blog } = props;
12 | const { code, ...rest } = blog;
13 |
14 | return (
15 | <>
16 |
17 |
18 |
{rest.emoji}
19 |
{rest.title}
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | >
29 | );
30 | }
31 |
--------------------------------------------------------------------------------
/packages/website/app/blog/[slug]/page.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import { Blog } from "@/shared";
3 | import { getAllBlogs, getBlogBySlug } from "@frontend-challenges/backend";
4 |
5 | import Client from "./client";
6 | import { bundleMarkdown } from "../../../utils/markdown";
7 |
8 | export async function generateStaticParams() {
9 | const posts = await getAllBlogs();
10 |
11 | const transformedPosts = posts.map((p) => ({
12 | slug: p.slug,
13 | }));
14 |
15 | return transformedPosts;
16 | }
17 |
18 | export async function generateMetadata({ params }: { params: any }) {
19 | const source = await getBlogBySlug(params.slug);
20 | const { frontmatter, code } = await bundleMarkdown(source);
21 | const post = { ...frontmatter, code } as Blog;
22 |
23 | return { title: post.title };
24 | }
25 |
26 | export default async function Page(props: any) {
27 | const source = await getBlogBySlug(props.params.slug);
28 | const { frontmatter, code } = await bundleMarkdown(source);
29 | const post = { ...frontmatter, code } as Blog;
30 |
31 | return ;
32 | }
33 |
--------------------------------------------------------------------------------
/packages/website/app/blog/page.tsx:
--------------------------------------------------------------------------------
1 | import { getAllBlogs } from "@frontend-challenges/backend";
2 |
3 | import Footer from "../../components/layout/Footer";
4 | import { Layout } from "../../components/layout/Layout";
5 | import { BlogList } from "../../components/blog/BlogList";
6 |
7 | export default async function Page() {
8 | const blogs = await getAllBlogs();
9 |
10 | return (
11 | <>
12 |
13 |
14 |
Blog
15 |
16 | Learn about the latest frontend technologies and best practices.
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | >
25 | );
26 | }
27 |
--------------------------------------------------------------------------------
/packages/website/app/categories/[category]/page.tsx:
--------------------------------------------------------------------------------
1 | import { CATEGORIES } from "@/shared";
2 | import { getChallenges } from "@frontend-challenges/backend";
3 | import { filterChallengesByCategory } from "../../../utils/challenges";
4 |
5 | import Client from "../../challenges/client";
6 |
7 | export const dynamic = "force-static";
8 | export const dynamicParams = false;
9 |
10 | export async function generateStaticParams() {
11 | return CATEGORIES.map((category) => ({
12 | category,
13 | }));
14 | }
15 |
16 | export default async function Page(props: any) {
17 | const challenges = await getChallenges();
18 | const challengesByCategory = filterChallengesByCategory(challenges, props.params.category);
19 |
20 | return ;
21 | }
22 |
--------------------------------------------------------------------------------
/packages/website/app/challenges/[slug]/ShareSolutionButton.tsx:
--------------------------------------------------------------------------------
1 | import { Button } from "@/web/components/ui";
2 | import { getShareAnswerURL } from "@/web/utils/answers";
3 | import { useSandpack } from "@codesandbox/sandpack-react";
4 | import { Challenge, SupportedTemplates } from "@/shared";
5 |
6 | type ShareSolutionProps = {
7 | challenge: Challenge;
8 | template?: SupportedTemplates;
9 | };
10 |
11 | export function ShareSolutionButton(props: ShareSolutionProps) {
12 | const { challenge, template } = props;
13 | const { sandpack } = useSandpack();
14 | const { files } = sandpack;
15 |
16 | const onClick = () => {
17 | const URL = getShareAnswerURL({
18 | challenge,
19 | template,
20 | files,
21 | });
22 |
23 | if (URL !== "") {
24 | window.open(URL, "_blank")?.focus();
25 | }
26 | };
27 |
28 | return (
29 |
32 | );
33 | }
34 |
--------------------------------------------------------------------------------
/packages/website/app/challenges/[slug]/client.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { Challenge } from "@/shared";
4 | import { useEventTracking } from "@/web/hooks/useAnalytics";
5 |
6 | import { Quiz } from "./Quiz";
7 | import { Question } from "./Question";
8 |
9 | type ClientProps = {
10 | challenge: Challenge;
11 | };
12 |
13 | export default function Client(props: ClientProps) {
14 | const { challenge } = props;
15 |
16 | const eventData = {
17 | challenge: challenge.no,
18 | title: challenge.info?.en?.title,
19 | };
20 |
21 | useEventTracking("Challenge Viewed", eventData, [challenge]);
22 |
23 | return challenge.type === "quiz" ? : ;
24 | }
25 |
--------------------------------------------------------------------------------
/packages/website/app/challenges/page.tsx:
--------------------------------------------------------------------------------
1 | import { getChallenges } from "@frontend-challenges/backend";
2 |
3 | import Client from "./client";
4 |
5 | export default async function Page() {
6 | const challenges = await getChallenges();
7 |
8 | return ;
9 | }
10 |
--------------------------------------------------------------------------------
/packages/website/app/client.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { useSyncScopeToSessionStorage } from "../hooks";
4 |
5 | type ClientProps = {
6 | children: React.ReactNode;
7 | };
8 |
9 | export function Client(props: ClientProps) {
10 | const { children } = props;
11 |
12 | useSyncScopeToSessionStorage("all");
13 |
14 | return <>{children}>;
15 | }
16 |
--------------------------------------------------------------------------------
/packages/website/app/play/loading.tsx:
--------------------------------------------------------------------------------
1 | import { Skeleton } from "../../components/ui/skeleton";
2 |
3 | export default function Loading() {
4 | return (
5 |
6 |
7 |
8 |
9 |
Playground
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | );
21 | }
22 |
--------------------------------------------------------------------------------
/packages/website/app/play/page.tsx:
--------------------------------------------------------------------------------
1 | import dynamic from "next/dynamic";
2 |
3 | import Loading from "./loading";
4 |
5 | const Client = dynamic(() => import("./client").then((mod) => mod.Client), {
6 | ssr: false,
7 | loading: Loading,
8 | });
9 |
10 | export default async function Page() {
11 | return ;
12 | }
13 |
--------------------------------------------------------------------------------
/packages/website/app/sitemap.ts:
--------------------------------------------------------------------------------
1 | import { MetadataRoute } from "next";
2 | import { DOMAIN } from "@/shared";
3 | import { getAllBlogs } from "@frontend-challenges/backend";
4 | import { getChallenges } from "@frontend-challenges/backend";
5 |
6 | export default async function sitemap(): Promise {
7 | const challenges = await getChallenges();
8 | const blogs = await getAllBlogs();
9 |
10 | return [
11 | {
12 | url: DOMAIN,
13 | },
14 | {
15 | url: `${DOMAIN}/challenges`,
16 | },
17 | {
18 | url: `${DOMAIN}/blog`,
19 | },
20 | ...challenges.map((challenge) => ({
21 | url: `${DOMAIN}/challenges/${challenge.path}`,
22 | })),
23 | ...blogs.map((blog) => ({
24 | url: `${DOMAIN}/${blog.path}`,
25 | })),
26 | ];
27 | }
28 |
--------------------------------------------------------------------------------
/packages/website/app/submit/question/Description.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Markdown from "react-markdown";
3 |
4 | import { components } from "../../../components/mdx";
5 | import { Badge, BadgeProps, Card } from "../../../components/ui";
6 |
7 | type DescriptionProps = {
8 | form: any;
9 | };
10 |
11 | function Description(props: DescriptionProps) {
12 | const { form } = props;
13 |
14 | return (
15 |
16 |
17 |
{form.getValues("title")}
18 |
19 | {form.getValues("difficulty")}
20 |
21 |
22 | {form.getValues("readme")}
23 |
24 |
25 |
26 | );
27 | }
28 |
29 | export { Description };
30 |
--------------------------------------------------------------------------------
/packages/website/app/submit/question/loading.tsx:
--------------------------------------------------------------------------------
1 | import { Skeleton } from "../../../components/ui/skeleton";
2 |
3 | export default function Loading() {
4 | return (
5 |
6 |
7 |
8 |
9 |
10 |
Submit Question
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | );
25 | }
26 |
--------------------------------------------------------------------------------
/packages/website/app/submit/question/page.tsx:
--------------------------------------------------------------------------------
1 | import dynamic from "next/dynamic";
2 | import Loading from "./loading";
3 |
4 | export const metadata = {
5 | title: "Submit",
6 | description: "Submit a new link",
7 | };
8 |
9 | const Client = dynamic(() => import("./client"), {
10 | ssr: false,
11 | loading: Loading,
12 | });
13 |
14 | export default function Page() {
15 | return ;
16 | }
17 |
--------------------------------------------------------------------------------
/packages/website/app/submit/quiz/Step2Header.tsx:
--------------------------------------------------------------------------------
1 | import { Button } from "../../../components/ui";
2 |
3 | type Step2HeaderProps = {
4 | setActiveTab: (tab: string) => void;
5 | };
6 |
7 | function Step2Header(props: Step2HeaderProps) {
8 | const { setActiveTab } = props;
9 |
10 | return (
11 |
12 |
13 |
Enter answer
14 |
Write the answer for the quiz
15 |
16 |
17 |
18 |
21 |
22 |
23 |
24 |
25 | );
26 | }
27 |
28 | export { Step2Header };
29 |
--------------------------------------------------------------------------------
/packages/website/app/submit/quiz/loading.tsx:
--------------------------------------------------------------------------------
1 | import { Skeleton } from "../../../components/ui/skeleton";
2 |
3 | export default function Loading() {
4 | return (
5 |
6 |
7 |
8 |
9 |
10 |
Submit Quiz
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | );
25 | }
26 |
--------------------------------------------------------------------------------
/packages/website/app/submit/quiz/page.tsx:
--------------------------------------------------------------------------------
1 | import dynamic from "next/dynamic";
2 |
3 | import Loading from "./loading";
4 |
5 | const Client = dynamic(() => import("./client"), {
6 | ssr: false,
7 | loading: Loading,
8 | });
9 |
10 | export const metadata = {
11 | title: "Submit",
12 | description: "Submit a new quiz",
13 | };
14 |
15 | export default function Page() {
16 | return ;
17 | }
18 |
--------------------------------------------------------------------------------
/packages/website/components.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://ui.shadcn.com/schema.json",
3 | "style": "new-york",
4 | "rsc": false,
5 | "tsx": true,
6 | "tailwind": {
7 | "config": "tailwind.config.js",
8 | "css": "app/globals.css",
9 | "baseColor": "slate",
10 | "cssVariables": true
11 | },
12 | "aliases": {
13 | "components": "@/components",
14 | "utils": "@/lib/utils"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/packages/website/components/auth/UserNav.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { UserDropdown } from "./UserDropdown";
4 | import { SignInButton } from "./SignInButton";
5 | import { Skeleton } from "../ui/skeleton";
6 | import { useAuth } from "@/web/hooks/useAuth";
7 |
8 | export default function LoginNav() {
9 | const auth = useAuth();
10 |
11 | if (auth.isLoading) return ;
12 |
13 | if (auth.user) return ;
14 |
15 | return ;
16 | }
17 |
--------------------------------------------------------------------------------
/packages/website/components/challenges/ChallengeList.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { Challenge } from "@/shared";
4 |
5 | import { cn } from "../../utils/helpers";
6 | import { ChallengeListItem } from "./ChallengeListItem";
7 | import type { ChallengeListItemProps } from "./ChallengeListItem";
8 |
9 | type ChallengeListProps = {
10 | challenges: Challenge[];
11 | showTypeIcon?: boolean;
12 | variant?: ChallengeListItemProps["variant"];
13 | };
14 |
15 | export function ChallengeList(props: ChallengeListProps) {
16 | const { challenges, variant = "default" } = props;
17 |
18 | return (
19 |
20 | {challenges.map((challenge) => (
21 |
22 | ))}
23 |
24 | );
25 | }
26 |
--------------------------------------------------------------------------------
/packages/website/components/challenges/filters-mobile/ChallengeTypeFilterMobile.tsx:
--------------------------------------------------------------------------------
1 | // ChallengeTypeFilterMobile.tsx
2 | import { CheckboxButton } from "../../ui/checkbox-button";
3 | import { ChallengeFilterState } from "../../../hooks/useFilteredChallenges";
4 |
5 | type ChallengeTypeFilterMobileProps = {
6 | state: ChallengeFilterState;
7 | dispatch: React.Dispatch;
8 | };
9 |
10 | export const ChallengeTypeFilterMobile = ({ state, dispatch }: ChallengeTypeFilterMobileProps) => {
11 | const handleTypeChange = (type: string) => {
12 | dispatch({
13 | type: type,
14 | });
15 | };
16 |
17 | return (
18 |
19 |
Type
20 |
21 | {["all", "question", "quiz"].map((type) => (
22 | handleTypeChange(type)}>
23 | {type}
24 |
25 | ))}
26 |
27 |
28 | );
29 | };
30 |
--------------------------------------------------------------------------------
/packages/website/components/challenges/filters/ChallengeCategoryFilter.tsx:
--------------------------------------------------------------------------------
1 | import { CATEGORIES } from "@/shared";
2 | import type { Category } from "@/shared";
3 |
4 | import { MultiSelect } from "../../ui/multi-select";
5 | import { ChallengeFilterDispatch, ChallengeFilterState } from "../../../hooks/useFilteredChallenges";
6 |
7 | type ChallengeDifficultyFilterProps = {
8 | dispatch: ChallengeFilterDispatch;
9 | state: ChallengeFilterState;
10 | };
11 |
12 | const categoryOptions = CATEGORIES.map((category) => ({ label: category, value: category }));
13 |
14 | export function ChallengeCategoryFilter(props: ChallengeDifficultyFilterProps) {
15 | const { state, dispatch } = props;
16 |
17 | const onValueChange = (values) =>
18 | dispatch({
19 | category: values as Category[],
20 | });
21 |
22 | return (
23 |
29 | );
30 | }
31 |
--------------------------------------------------------------------------------
/packages/website/components/challenges/filters/ChallengeDifficultyFilter.tsx:
--------------------------------------------------------------------------------
1 | import { DIFFICULTY_RANK } from "@/shared";
2 | import type { Difficulty } from "@/shared";
3 |
4 | import { MultiSelect } from "../../ui/multi-select";
5 | import { ChallengeFilterDispatch, ChallengeFilterState } from "../../../hooks/useFilteredChallenges";
6 |
7 | type ChallengeDifficultyFilterProps = {
8 | dispatch: ChallengeFilterDispatch;
9 | state: ChallengeFilterState;
10 | };
11 |
12 | const difficultyOptions = DIFFICULTY_RANK.map((difficulty) => ({ label: difficulty, value: difficulty }));
13 |
14 | export function ChallengeDifficultyFilter(props: ChallengeDifficultyFilterProps) {
15 | const { state, dispatch } = props;
16 |
17 | const onValueChange = (values) =>
18 | dispatch({
19 | difficulty: values as Difficulty[],
20 | });
21 |
22 | return (
23 |
29 | );
30 | }
31 |
--------------------------------------------------------------------------------
/packages/website/components/challenges/filters/ChallengeSearchFilter.tsx:
--------------------------------------------------------------------------------
1 | import { Input } from "../../ui/input";
2 | import { ChallengeFilterState } from "../../../hooks/useFilteredChallenges";
3 |
4 | type ChallengeSearchFilterProps = {
5 | state: ChallengeFilterState;
6 | dispatch: React.Dispatch;
7 | };
8 |
9 | export const ChallengeSearchFilter = ({ state, dispatch }: ChallengeSearchFilterProps) => {
10 | return (
11 | {
16 | dispatch({ search: e.target.value });
17 | }}
18 | />
19 | );
20 | };
21 |
--------------------------------------------------------------------------------
/packages/website/components/challenges/filters/ChallengeTypeFilter.tsx:
--------------------------------------------------------------------------------
1 | import { ToggleGroup, ToggleGroupItem } from "../../ui";
2 | import { ChallengeFilterDispatch, ChallengeFilterState } from "../../../hooks/useFilteredChallenges";
3 |
4 | type ChallegneTypeFilterProps = {
5 | dispatch: ChallengeFilterDispatch;
6 | state: ChallengeFilterState;
7 | };
8 |
9 | export function ChallengeTypeFilter(props: ChallegneTypeFilterProps) {
10 | const { state, dispatch } = props;
11 |
12 | const onValueChange = (value) => {
13 | if (!value) return;
14 |
15 | dispatch({
16 | type: value as any,
17 | });
18 | };
19 |
20 | return (
21 |
28 | All
29 | Question
30 | Quiz
31 |
32 | );
33 | }
34 |
--------------------------------------------------------------------------------
/packages/website/components/common/MDXComponent.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import React from "react";
4 | import { getMDXComponent } from "mdx-bundler/client";
5 | import { components } from "../mdx";
6 |
7 | function MDXComponent(props: any) {
8 | const Comp = getMDXComponent(props.code);
9 |
10 | return (
11 |
12 |
13 |
14 | );
15 | }
16 |
17 | export { MDXComponent };
18 |
--------------------------------------------------------------------------------
/packages/website/components/common/ThemeChanger.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { useTheme } from "next-themes";
4 | import React from "react";
5 | import { Icon, ToggleGroup, ToggleGroupItem } from "../ui";
6 |
7 | export default function ThemeChanger() {
8 | const { theme, setTheme } = useTheme();
9 |
10 | const onValueChange = (value: string) => {
11 | if (value === "" || value === theme) return;
12 |
13 | setTheme(value);
14 | };
15 |
16 | return (
17 | <>
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | >
30 | );
31 | }
32 |
--------------------------------------------------------------------------------
/packages/website/components/editor/types.ts:
--------------------------------------------------------------------------------
1 | export type DropZone = "top" | "right" | "bottom" | "left" | null;
2 |
3 | export interface DragAndDropProps {
4 | path: number[];
5 | draggable?: boolean;
6 | updateLayout: (onDroppingItemPath: number[], dropZone: DropZone) => void;
7 | sourceItemPath: number[] | null;
8 | setSourceItemPath: (path: number[] | null) => void;
9 | direction: "horizontal" | "vertical";
10 | }
11 |
--------------------------------------------------------------------------------
/packages/website/components/home/HeroImage.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Logo } from "../common/Logo";
3 |
4 | export function HeroImage() {
5 | return (
6 |
12 | );
13 | }
14 |
--------------------------------------------------------------------------------
/packages/website/components/home/RecentlyAddedChallenges.tsx:
--------------------------------------------------------------------------------
1 | import { Challenge } from "@/shared";
2 |
3 | import { ChallengeList } from "../challenges/ChallengeList";
4 |
5 | type RecentlyAddedChallengesProps = {
6 | challenges: Challenge[];
7 | };
8 |
9 | export function RecentlyAddedChallenges(props: RecentlyAddedChallengesProps) {
10 | const { challenges } = props;
11 |
12 | return (
13 |
14 |
15 |
Recently Added
16 |
The newest challenges added by the community
17 |
18 |
19 |
20 | );
21 | }
22 |
--------------------------------------------------------------------------------
/packages/website/components/icons/ArrowDownIcon.tsx:
--------------------------------------------------------------------------------
1 | import { ComponentProps } from "react";
2 |
3 | export const ArrowDownIcon = (props: ComponentProps<"svg">) => (
4 |
22 | );
23 |
--------------------------------------------------------------------------------
/packages/website/components/icons/ArrowUpIcon.tsx:
--------------------------------------------------------------------------------
1 | import { ComponentProps } from "react";
2 |
3 | export const ArrowUpIcon = (props: ComponentProps<"svg">) => (
4 |
22 | );
23 |
--------------------------------------------------------------------------------
/packages/website/components/icons/BugIcon.tsx:
--------------------------------------------------------------------------------
1 | import React, { ComponentProps } from "react";
2 |
3 | export function BugIcon(props: ComponentProps<"svg">) {
4 | return (
5 |
15 | );
16 | }
17 |
--------------------------------------------------------------------------------
/packages/website/components/icons/ChallengeIcon.tsx:
--------------------------------------------------------------------------------
1 | import React, { ComponentProps } from "react";
2 |
3 | export function ChallengeIcon(props: ComponentProps<"svg">) {
4 | return (
5 |
23 | );
24 | }
25 |
--------------------------------------------------------------------------------
/packages/website/components/icons/CheckIcon.tsx:
--------------------------------------------------------------------------------
1 | import { ComponentProps } from "react";
2 |
3 | export const CheckIcon = (props: ComponentProps<"svg">) => (
4 |
22 | );
23 |
--------------------------------------------------------------------------------
/packages/website/components/icons/ChevronDownIcon.tsx:
--------------------------------------------------------------------------------
1 | import React, { ComponentProps } from "react";
2 |
3 | export function ChevronDownIcon(props: ComponentProps<"svg">) {
4 | return (
5 |
14 | );
15 | }
16 |
--------------------------------------------------------------------------------
/packages/website/components/icons/ChevronLeftIcon.tsx:
--------------------------------------------------------------------------------
1 | import React, { ComponentProps } from "react";
2 |
3 | export function ChevronLeftIcon(props: ComponentProps<"svg">) {
4 | return (
5 |
15 | );
16 | }
17 |
--------------------------------------------------------------------------------
/packages/website/components/icons/ChevronRightIcon.tsx:
--------------------------------------------------------------------------------
1 | import React, { ComponentProps } from "react";
2 |
3 | export function ChevronRightIcon(props: ComponentProps<"svg">) {
4 | return (
5 |
15 | );
16 | }
17 |
--------------------------------------------------------------------------------
/packages/website/components/icons/ChevronUpIcon.tsx:
--------------------------------------------------------------------------------
1 | import React, { ComponentProps } from "react";
2 |
3 | export function ChevronUpIcon(props: ComponentProps<"svg">) {
4 | return (
5 |
15 | );
16 | }
17 |
--------------------------------------------------------------------------------
/packages/website/components/icons/CollapseHorizontalIcon.tsx:
--------------------------------------------------------------------------------
1 | import { ComponentProps } from "react";
2 |
3 | export const CollapseHorizontalIcon = (props: ComponentProps<"svg">) => (
4 |
21 | );
22 |
--------------------------------------------------------------------------------
/packages/website/components/icons/CollapseVerticalIcon.tsx:
--------------------------------------------------------------------------------
1 | import { ComponentProps } from "react";
2 |
3 | export const CollapseVerticalIcon = (props: ComponentProps<"svg">) => (
4 |
21 | );
22 |
--------------------------------------------------------------------------------
/packages/website/components/icons/CssColorIcon.tsx:
--------------------------------------------------------------------------------
1 | import { ComponentProps } from "react";
2 |
3 | export const CssColorIcon = (props: ComponentProps<"svg">) => {
4 | return (
5 |
13 | );
14 | };
15 |
--------------------------------------------------------------------------------
/packages/website/components/icons/ExpandHorizontalIcon.tsx:
--------------------------------------------------------------------------------
1 | import { ComponentProps } from "react";
2 |
3 | export const ExpandHorizontalIcon = (props: ComponentProps<"svg">) => (
4 |
21 | );
22 |
--------------------------------------------------------------------------------
/packages/website/components/icons/ExpandVerticalIcon.tsx:
--------------------------------------------------------------------------------
1 | import { ComponentProps } from "react";
2 |
3 | export const ExpandVerticalIcon = (props: ComponentProps<"svg">) => (
4 |
21 | );
22 |
--------------------------------------------------------------------------------
/packages/website/components/icons/FilterIcon.tsx:
--------------------------------------------------------------------------------
1 | import { ComponentProps } from "react";
2 |
3 | export const FilterIcon = (props: ComponentProps<"svg">) => (
4 |
14 | );
15 |
--------------------------------------------------------------------------------
/packages/website/components/icons/HomeIcon.tsx:
--------------------------------------------------------------------------------
1 | import React, { ComponentProps } from "react";
2 |
3 | export function HomeIcon(props: ComponentProps<"svg">) {
4 | return (
5 |
23 | );
24 | }
25 |
--------------------------------------------------------------------------------
/packages/website/components/icons/Layout1Icon.tsx:
--------------------------------------------------------------------------------
1 | import { ComponentProps } from "react";
2 |
3 | export const Layout1Icon = (props: ComponentProps<"svg">) => {
4 | return (
5 |
28 | );
29 | };
30 |
--------------------------------------------------------------------------------
/packages/website/components/icons/Layout2Icon.tsx:
--------------------------------------------------------------------------------
1 | import { ComponentProps } from "react";
2 |
3 | export const Layout2Icon = (props: ComponentProps<"svg">) => {
4 | return (
5 |
28 | );
29 | };
30 |
--------------------------------------------------------------------------------
/packages/website/components/icons/Layout3Icon.tsx:
--------------------------------------------------------------------------------
1 | import { ComponentProps } from "react";
2 |
3 | export const Layout3Icon = (props: ComponentProps<"svg">) => {
4 | return (
5 |
28 | );
29 | };
30 |
--------------------------------------------------------------------------------
/packages/website/components/icons/LinkedinIcon.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 |
3 | export function LinkedinIcon(props: React.ComponentProps<"svg">) {
4 | return (
5 |
16 | );
17 | }
18 |
--------------------------------------------------------------------------------
/packages/website/components/icons/ListIcon.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { ComponentProps } from "react";
3 |
4 | function ListIcon(props: ComponentProps<"svg">) {
5 | return (
6 |
11 | );
12 | }
13 |
14 | export { ListIcon };
15 |
--------------------------------------------------------------------------------
/packages/website/components/icons/LockIcon.tsx:
--------------------------------------------------------------------------------
1 | import React, { ComponentProps } from "react";
2 |
3 | export function LockIcon(props: ComponentProps<"svg">) {
4 | return (
5 |
26 | );
27 | }
28 |
--------------------------------------------------------------------------------
/packages/website/components/icons/LogAllIcon.tsx:
--------------------------------------------------------------------------------
1 | import React, { ComponentProps } from "react";
2 |
3 | export function LogAllIcon(props: ComponentProps<"svg">) {
4 | return (
5 |
10 | );
11 | }
12 |
--------------------------------------------------------------------------------
/packages/website/components/icons/LogClearIcon.tsx:
--------------------------------------------------------------------------------
1 | import React, { ComponentProps } from "react";
2 |
3 | export function LogClearIcon(props: ComponentProps<"svg">) {
4 | return (
5 |
15 | );
16 | }
17 |
--------------------------------------------------------------------------------
/packages/website/components/icons/LogErrorIcon.tsx:
--------------------------------------------------------------------------------
1 | import React, { ComponentProps } from "react";
2 |
3 | export function LogErrorIcon(props: ComponentProps<"svg">) {
4 | return (
5 |
15 | );
16 | }
17 |
--------------------------------------------------------------------------------
/packages/website/components/icons/LogInfoIcon.tsx:
--------------------------------------------------------------------------------
1 | import React, { ComponentProps } from "react";
2 |
3 | export function LogInfoIcon(props: ComponentProps<"svg">) {
4 | return (
5 |
25 | );
26 | }
27 |
--------------------------------------------------------------------------------
/packages/website/components/icons/LogiWarningIcon.tsx:
--------------------------------------------------------------------------------
1 | import React, { ComponentProps } from "react";
2 |
3 | export function LogWarningIcon(props: ComponentProps<"svg">) {
4 | return (
5 |
26 | );
27 | }
28 |
--------------------------------------------------------------------------------
/packages/website/components/icons/SortIcon.tsx:
--------------------------------------------------------------------------------
1 | import { ComponentProps } from "react";
2 |
3 | export const SortIcon = (props: ComponentProps<"svg">) => (
4 |
30 | );
31 |
--------------------------------------------------------------------------------
/packages/website/components/icons/SpinnerIcon.tsx:
--------------------------------------------------------------------------------
1 | import { ComponentProps } from "react";
2 |
3 | export const SpinnerIcon = (props: ComponentProps<"svg">) => {
4 | return (
5 |
13 | );
14 | };
15 |
--------------------------------------------------------------------------------
/packages/website/components/icons/TidyIcon.tsx:
--------------------------------------------------------------------------------
1 | import React, { ComponentProps } from "react";
2 |
3 | export function TidyIcon(props: ComponentProps<"svg">) {
4 | return (
5 |
14 | );
15 | }
16 |
--------------------------------------------------------------------------------
/packages/website/components/icons/TypescriptColorIcon.tsx:
--------------------------------------------------------------------------------
1 | import { ComponentProps } from "react";
2 |
3 | export const TypescriptColorIcon = (props: ComponentProps<"svg">) => (
4 |
12 | );
13 |
--------------------------------------------------------------------------------
/packages/website/components/icons/UserIcon.tsx:
--------------------------------------------------------------------------------
1 | import { ComponentProps } from "react";
2 |
3 | export const UserIcon = (props: ComponentProps<"svg">) => (
4 |
22 | );
23 |
--------------------------------------------------------------------------------
/packages/website/components/icons/VanillaColorIcon.tsx:
--------------------------------------------------------------------------------
1 | import { ComponentProps } from "react";
2 |
3 | export const VanillaColorIcon = (props: ComponentProps<"svg">) => {
4 | return (
5 |
20 | );
21 | };
22 |
--------------------------------------------------------------------------------
/packages/website/components/icons/VerticalDotsIcon.tsx:
--------------------------------------------------------------------------------
1 | import React, { ComponentProps } from "react";
2 |
3 | export function VerticalDotsIcon(props: ComponentProps<"svg">) {
4 | return (
5 |
15 | );
16 | }
17 |
18 | export default VerticalDotsIcon;
19 |
--------------------------------------------------------------------------------
/packages/website/components/icons/VueColorIcon.tsx:
--------------------------------------------------------------------------------
1 | import { ComponentProps } from "react";
2 |
3 | export const VueColorIcon = (props: ComponentProps<"svg">) => {
4 | return (
5 |
17 | );
18 | };
19 |
--------------------------------------------------------------------------------
/packages/website/components/icons/XIcon.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 |
3 | export function XIcon(props: React.ComponentProps<"svg">) {
4 | return (
5 |
11 | );
12 | }
13 |
--------------------------------------------------------------------------------
/packages/website/components/layout/Layout.tsx:
--------------------------------------------------------------------------------
1 | import { cn } from "../../utils/helpers";
2 |
3 | type LayoutProps = {
4 | children: React.ReactNode;
5 | className?: string;
6 | };
7 |
8 | export function Layout(props: LayoutProps) {
9 | const { children, className } = props;
10 |
11 | return (
12 |
13 | {children}
14 |
15 | );
16 | }
17 |
--------------------------------------------------------------------------------
/packages/website/components/markdown/Paragraph.tsx:
--------------------------------------------------------------------------------
1 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
2 | function Paragraph(props: any) {
3 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
4 | const { node, ...rest } = props;
5 |
6 | return ;
7 | }
8 |
9 | export { Paragraph };
10 |
--------------------------------------------------------------------------------
/packages/website/components/markdown/Pre.tsx:
--------------------------------------------------------------------------------
1 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
2 | function Pre(props: any) {
3 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
4 | const { node, ...rest } = props;
5 |
6 | return ;
7 | }
8 |
9 | export { Pre };
10 |
--------------------------------------------------------------------------------
/packages/website/components/markdown/index.tsx:
--------------------------------------------------------------------------------
1 | /* eslint-disable @typescript-eslint/no-unused-vars */
2 | import { Pre } from "./Pre";
3 | import { Paragraph } from "./Paragraph";
4 |
5 | const components = {
6 | p: Paragraph,
7 | pre: Pre,
8 | ul: ({ node, ...props }: any) => ,
9 | li: ({ node, ...props }: any) => ,
10 | h3: ({ node, ...props }: any) => ,
11 | };
12 |
13 | export { components };
14 |
--------------------------------------------------------------------------------
/packages/website/components/roadmaps/RoadmapListItem.tsx:
--------------------------------------------------------------------------------
1 | import { Roadmap } from "@/shared";
2 |
3 | import { Card, Link } from "../ui";
4 |
5 | function RoadmapListItem(props: { studyPlan: Roadmap }) {
6 | const { studyPlan } = props;
7 |
8 | return (
9 |
10 |
11 |
12 |
13 |
17 | {studyPlan.info.en?.title}
18 |
19 |
20 |
21 |
{studyPlan.info.en?.description}
22 |
23 |
24 | );
25 | }
26 |
27 | export { RoadmapListItem };
28 |
--------------------------------------------------------------------------------
/packages/website/components/ui/aspect-ratio.tsx:
--------------------------------------------------------------------------------
1 | import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio";
2 |
3 | const AspectRatio = AspectRatioPrimitive.Root;
4 |
5 | export { AspectRatio };
6 |
--------------------------------------------------------------------------------
/packages/website/components/ui/collapsible.tsx:
--------------------------------------------------------------------------------
1 | import * as CollapsiblePrimitive from "@radix-ui/react-collapsible";
2 |
3 | const Collapsible = CollapsiblePrimitive.Root;
4 |
5 | const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger;
6 |
7 | const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent;
8 |
9 | export { Collapsible, CollapsibleTrigger, CollapsibleContent };
10 |
--------------------------------------------------------------------------------
/packages/website/components/ui/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./select";
2 | export * from "./button";
3 | export * from "./icon";
4 | export * from "./breadcrumb";
5 | export * from "./accordion";
6 | export * from "./input";
7 | export * from "./form";
8 | export * from "./card";
9 | export * from "./tabs";
10 | export * from "./textarea";
11 | export * from "./toggle";
12 | export * from "./toggle-group";
13 | export * from "./badge";
14 | export * from "./checkbox";
15 | export * from "./radio-group";
16 | export * from "./dialog";
17 | export * from "./label";
18 | export * from "./scroll-area";
19 | export * from "./resizable";
20 | export * from "./command";
21 | export * from "./icon-button";
22 | export * from "./tooltip";
23 | export * from "./sheet";
24 | export * from "./separator";
25 | export * from "./checkbox-button";
26 | export * from "./skeleton";
27 | export * from "./link";
28 |
--------------------------------------------------------------------------------
/packages/website/components/ui/input.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 |
3 | import { cn } from "../../utils/helpers";
4 |
5 | export interface InputProps extends React.InputHTMLAttributes {
6 | isQuiet?: boolean;
7 | }
8 |
9 | const Input = React.forwardRef(({ className, type, ...props }, ref) => {
10 | return (
11 |
22 | );
23 | });
24 | Input.displayName = "Input";
25 |
26 | export { Input };
27 |
--------------------------------------------------------------------------------
/packages/website/components/ui/label.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import * as LabelPrimitive from "@radix-ui/react-label";
3 | import { cva, type VariantProps } from "class-variance-authority";
4 |
5 | import { cn } from "../../utils/helpers";
6 |
7 | const labelVariants = cva("text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70");
8 |
9 | const Label = React.forwardRef<
10 | React.ElementRef,
11 | React.ComponentPropsWithoutRef & VariantProps
12 | >(({ className, ...props }, ref) => (
13 |
14 | ));
15 | Label.displayName = LabelPrimitive.Root.displayName;
16 |
17 | export { Label };
18 |
--------------------------------------------------------------------------------
/packages/website/components/ui/link.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import * as React from "react";
4 | import NextLink from "next/link";
5 |
6 | const Link = React.forwardRef, React.ComponentPropsWithoutRef>(
7 | ({ prefetch, ...props }, ref) => ,
8 | );
9 |
10 | Link.displayName = "Link";
11 |
12 | export { Link };
13 |
--------------------------------------------------------------------------------
/packages/website/components/ui/progress.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import * as ProgressPrimitive from "@radix-ui/react-progress";
3 |
4 | import { cn } from "../../utils/helpers";
5 |
6 | const Progress = React.forwardRef<
7 | React.ElementRef,
8 | React.ComponentPropsWithoutRef
9 | >(({ className, value, ...props }, ref) => (
10 |
15 |
19 |
20 | ));
21 | Progress.displayName = ProgressPrimitive.Root.displayName;
22 |
23 | export { Progress };
24 |
--------------------------------------------------------------------------------
/packages/website/components/ui/separator.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import * as React from "react";
4 | import * as SeparatorPrimitive from "@radix-ui/react-separator";
5 |
6 | import { cn } from "../../utils/helpers";
7 |
8 | const Separator = React.forwardRef<
9 | React.ElementRef,
10 | React.ComponentPropsWithoutRef
11 | >(({ className, orientation = "horizontal", decorative = true, ...props }, ref) => (
12 |
23 | ));
24 | Separator.displayName = SeparatorPrimitive.Root.displayName;
25 |
26 | export { Separator };
27 |
--------------------------------------------------------------------------------
/packages/website/components/ui/skeleton.tsx:
--------------------------------------------------------------------------------
1 | import { cn } from "../../utils/helpers";
2 |
3 | function Skeleton({ className, ...props }: React.HTMLAttributes) {
4 | return ;
5 | }
6 |
7 | export { Skeleton };
8 |
--------------------------------------------------------------------------------
/packages/website/components/ui/textarea.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 |
3 | import { cn } from "../../utils/helpers";
4 |
5 | export interface TextareaProps extends React.TextareaHTMLAttributes {}
6 |
7 | const Textarea = React.forwardRef(({ className, ...props }, ref) => {
8 | return (
9 |
18 | );
19 | });
20 | Textarea.displayName = "Textarea";
21 |
22 | export { Textarea };
23 |
--------------------------------------------------------------------------------
/packages/website/components/ui/toaster.tsx:
--------------------------------------------------------------------------------
1 | import { useToast } from "./use-toast";
2 | import { Toast, ToastClose, ToastDescription, ToastProvider, ToastTitle, ToastViewport } from "./toast";
3 |
4 | export function Toaster() {
5 | const { toasts } = useToast();
6 |
7 | return (
8 |
9 | {toasts.map(function ({ id, title, description, action, ...props }) {
10 | return (
11 |
12 |
13 | {title && {title}}
14 | {description && {description}}
15 |
16 | {action}
17 |
18 |
19 | );
20 | })}
21 |
22 |
23 | );
24 | }
25 |
--------------------------------------------------------------------------------
/packages/website/db/auth.ts:
--------------------------------------------------------------------------------
1 | import { supabase } from "@/web/utils/supabase/client";
2 |
3 | export async function getAuthUser() {
4 | const session = await supabase.auth.getSession();
5 |
6 | if (!session.data.session) return Promise.resolve(null);
7 |
8 | const userData = await supabase.auth.getUser();
9 |
10 | if (!userData.data.user) return Promise.resolve(null);
11 |
12 | return supabase.from("profiles").select("*").eq("id", userData.data.user.id);
13 | }
14 |
--------------------------------------------------------------------------------
/packages/website/db/completions.ts:
--------------------------------------------------------------------------------
1 | import { supabase } from "@/web/utils/supabase/client";
2 |
3 | export async function createCompletion({ challenge_id, user_id }) {
4 | return supabase.from("completions").insert({
5 | challenge_id: challenge_id,
6 | user_id: user_id,
7 | });
8 | }
9 |
10 | export async function deleteCompletion({ challenge_id, user_id }) {
11 | return supabase.from("completions").delete().eq("challenge_id", challenge_id).eq("user_id", user_id);
12 | }
13 |
14 | export async function getCompletions({ user_id }) {
15 | return supabase.from("completions").select("*").eq("user_id", user_id);
16 | }
17 |
--------------------------------------------------------------------------------
/packages/website/db/notes.ts:
--------------------------------------------------------------------------------
1 | import { supabase } from "@/web/utils/supabase/client";
2 |
3 | export async function createNote({ path, user_id, content }) {
4 | return supabase.from("notes").insert({
5 | path,
6 | user_id,
7 | content,
8 | });
9 | }
10 |
11 | export async function getNote({ user_id, path }) {
12 | return supabase.from("notes").select("*").eq("user_id", user_id).eq("path", path).limit(1).single();
13 | }
14 |
15 | export async function updateNote({ user_id, path, content }) {
16 | return supabase.from("notes").upsert({ path, content, user_id }).eq("user_id", user_id).eq("path", path);
17 | }
18 |
19 | export async function deleteNote({ path, user_id }) {
20 | return supabase.from("notes").delete().eq("path", path).eq("user_id", user_id);
21 | }
22 |
--------------------------------------------------------------------------------
/packages/website/hooks/index.ts:
--------------------------------------------------------------------------------
1 | export { useForceUpdate } from "./utils/useForceUpdate";
2 | export { useInitializeFilters } from "./useInitializeFilters";
3 | export { useSyncScopeToSessionStorage } from "./useSyncScopeToSessionStorage";
4 |
--------------------------------------------------------------------------------
/packages/website/hooks/useAnalytics.ts:
--------------------------------------------------------------------------------
1 | // hooks/useAnalytics.ts
2 | import { useEffect } from "react";
3 | import { analytics } from "packages/website/analytics";
4 | import { AnalyticsEventName } from "../analytics/events";
5 |
6 | export function useEventTracking(
7 | eventName: AnalyticsEventName,
8 | properties?: Record,
9 | dependencies: any[] = [],
10 | ) {
11 | useEffect(() => {
12 | analytics.track(eventName, properties);
13 | }, dependencies);
14 | }
15 |
--------------------------------------------------------------------------------
/packages/website/hooks/useAnswers.ts:
--------------------------------------------------------------------------------
1 | import { useQuery } from "@tanstack/react-query";
2 | import { getAnswersOfQuestion } from "../utils/answers";
3 |
4 | export function useAnswers(...args: Parameters) {
5 | const answersQuery = useQuery({
6 | queryKey: ["answers", args["0"].no],
7 | queryFn: async () => {
8 | return getAnswersOfQuestion(...args);
9 | },
10 | });
11 |
12 | return { isLoading: answersQuery.isPending, answers: answersQuery.data };
13 | }
14 |
--------------------------------------------------------------------------------
/packages/website/hooks/useAuth.ts:
--------------------------------------------------------------------------------
1 | import { getAuthUser } from "@/web/db/auth";
2 | import { useQuery } from "@tanstack/react-query";
3 |
4 | export function useAuth() {
5 | const profileQuery = useQuery({
6 | queryKey: ["user"],
7 | queryFn: getAuthUser,
8 | });
9 |
10 | return { isLoading: profileQuery.isPending, user: profileQuery.data?.data?.[0] };
11 | }
12 |
--------------------------------------------------------------------------------
/packages/website/hooks/useChallengeFiles.ts:
--------------------------------------------------------------------------------
1 | import { Question, SupportedTemplates, TEMPLATES } from "@/shared";
2 | import { useLocalStorage } from "./useLocalStorage";
3 |
4 | export function useChallengeFiles(challenge: Question, template: SupportedTemplates) {
5 | const cachedFiles = useLocalStorage(`/challenges/${challenge.path}-${template}`);
6 |
7 | const allFiles = { ...TEMPLATES[template].files, ...challenge.templateFiles[template], ...cachedFiles };
8 |
9 | const availableFiles = Object.keys(allFiles)
10 | .filter((file) => !allFiles[file].hidden)
11 | .reduce((acc, file) => {
12 | acc[file] = allFiles[file];
13 | return acc;
14 | }, {});
15 |
16 | return { availableFiles, allFiles };
17 | }
18 |
--------------------------------------------------------------------------------
/packages/website/hooks/useCompletions.ts:
--------------------------------------------------------------------------------
1 | import { useQuery } from "@tanstack/react-query";
2 |
3 | import { getCompletions } from "../db/completions";
4 | import { useAuth } from "./useAuth";
5 |
6 | export function useCompletions() {
7 | const auth = useAuth();
8 | const completionsQuery = useQuery({
9 | queryKey: ["completions"],
10 | queryFn: () => {
11 | return getCompletions({ user_id: auth.user.id });
12 | },
13 | enabled: !!auth.user,
14 | });
15 |
16 | const completions = completionsQuery.data?.data?.map((c) => c.challenge_id) ?? [];
17 |
18 | return { completions, isLoading: completionsQuery.isFetching };
19 | }
20 |
--------------------------------------------------------------------------------
/packages/website/hooks/useDebounce.ts:
--------------------------------------------------------------------------------
1 | import debounce from "lodash/debounce";
2 | import React, { useRef } from "react";
3 |
4 | export function useDebounce(callback: (...args: any[]) => void, delay: number) {
5 | const callbackRef = useRef(callback);
6 |
7 | React.useLayoutEffect(() => {
8 | callbackRef.current = callback;
9 | });
10 |
11 | return React.useMemo(() => debounce((...args) => callbackRef.current(...args), delay), [delay]);
12 | }
13 |
--------------------------------------------------------------------------------
/packages/website/hooks/useLocalStorage.ts:
--------------------------------------------------------------------------------
1 | import { STORAGE_KEY } from "@/shared";
2 |
3 | export function useLocalStorage(path: string) {
4 | try {
5 | const files = localStorage.getItem(`${STORAGE_KEY}:${path}`);
6 |
7 | return JSON.parse(files);
8 | } catch {
9 | return {};
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/packages/website/hooks/useMobile.ts:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 |
3 | const MOBILE_BREAKPOINT = 768;
4 |
5 | export function useIsMobile() {
6 | const [isMobile, setIsMobile] = React.useState(undefined);
7 |
8 | React.useEffect(() => {
9 | const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
10 | const onChange = () => {
11 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
12 | };
13 | mql.addEventListener("change", onChange);
14 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
15 | return () => mql.removeEventListener("change", onChange);
16 | }, []);
17 |
18 | return !!isMobile;
19 | }
20 |
--------------------------------------------------------------------------------
/packages/website/hooks/useSyncScopeToSessionStorage.ts:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { STORAGE_KEY } from "@/shared";
4 | import { useEffect } from "react";
5 |
6 | /**
7 | * Sync the scope to session storage.
8 | *
9 | * This allows the scope to be used on the challenges page. The scope acts
10 | * as a context for both the challenge list page and individual challenge pages.
11 | * For example, if you navigate to React challenges, the scope will be "react".
12 | * When you then navigate to a specific challenge, the scope remains "react",
13 | * ensuring that the challenge list displays only React challenges.
14 | *
15 | * @param scope
16 | */
17 | export function useSyncScopeToSessionStorage(scope: string) {
18 | useEffect(() => {
19 | sessionStorage.setItem(`${STORAGE_KEY}:scope`, scope);
20 | }, [scope]);
21 | }
22 |
--------------------------------------------------------------------------------
/packages/website/hooks/utils/useForceUpdate.ts:
--------------------------------------------------------------------------------
1 | import { useReducer } from "react";
2 |
3 | const reducer = (value: number) => (value + 1) % 1000000;
4 |
5 | export function useForceUpdate(): () => void {
6 | const [, update] = useReducer(reducer, 0);
7 | return update;
8 | }
9 |
--------------------------------------------------------------------------------
/packages/website/next.config.js:
--------------------------------------------------------------------------------
1 | // https://nextjs.org/docs/api-reference/next.config.js/introduction
2 | module.exports = {
3 | reactStrictMode: false,
4 | };
5 |
--------------------------------------------------------------------------------
/packages/website/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | };
7 |
--------------------------------------------------------------------------------
/packages/website/providers/AuthProvider.tsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/frontend-challenges/81bd0e5a3b27fc84925a7ad431f12c973e81c9c6/packages/website/providers/AuthProvider.tsx
--------------------------------------------------------------------------------
/packages/website/providers/ChallengesProvider.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { createContext, useContext } from "react";
4 |
5 | import { Challenge } from "@/shared";
6 |
7 | export const ChallengesContext = createContext<{ challenges: Challenge[] }>({
8 | challenges: [],
9 | });
10 |
11 | type ChallengeProviderProps = {
12 | children: React.ReactNode;
13 | challenges: Challenge[];
14 | };
15 |
16 | export function ChallengesProvider(props: ChallengeProviderProps) {
17 | const { children, challenges } = props;
18 |
19 | return (
20 |
25 | {children}
26 |
27 | );
28 | }
29 |
30 | export function useChallenges() {
31 | return useContext(ChallengesContext);
32 | }
33 |
--------------------------------------------------------------------------------
/packages/website/providers/QueryProvider.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { useState } from "react";
4 | import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
5 |
6 | export function QueryProvider({ children }) {
7 | const [queryClient] = useState(
8 | () =>
9 | new QueryClient({
10 | defaultOptions: {
11 | queries: {
12 | staleTime: Infinity,
13 | },
14 | },
15 | }),
16 | );
17 |
18 | return {children};
19 | }
20 |
--------------------------------------------------------------------------------
/packages/website/providers/ThemeProvider.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import * as React from "react";
4 | import { type ThemeProviderProps } from "next-themes/dist/types";
5 | import { ThemeProvider as NextThemesProvider } from "next-themes";
6 |
7 | export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
8 | return (
9 |
10 | {children}
11 |
12 | );
13 | }
14 |
--------------------------------------------------------------------------------
/packages/website/providers/index.tsx:
--------------------------------------------------------------------------------
1 | import { Challenge } from "@/shared";
2 |
3 | import { ThemeProvider } from "./ThemeProvider";
4 | import { QueryProvider } from "./QueryProvider";
5 | import { LayoutProvider } from "./LayoutProvider";
6 | import { TooltipProvider } from "../components/ui";
7 | import { ChallengesProvider } from "./ChallengesProvider";
8 |
9 | type ProviderProps = {
10 | children: React.ReactNode;
11 | challenges: Challenge[];
12 | };
13 |
14 | export function Provider(props: ProviderProps) {
15 | const { children, challenges } = props;
16 |
17 | return (
18 |
19 |
20 |
21 |
22 |
23 | {children}
24 |
25 |
26 |
27 |
28 |
29 | );
30 | }
31 |
--------------------------------------------------------------------------------
/packages/website/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/frontend-challenges/81bd0e5a3b27fc84925a7ad431f12c973e81c9c6/packages/website/public/favicon.ico
--------------------------------------------------------------------------------
/packages/website/public/images/auth-github-bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/frontend-challenges/81bd0e5a3b27fc84925a7ad431f12c973e81c9c6/packages/website/public/images/auth-github-bg.png
--------------------------------------------------------------------------------
/packages/website/public/images/logo-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/frontend-challenges/81bd0e5a3b27fc84925a7ad431f12c973e81c9c6/packages/website/public/images/logo-2.png
--------------------------------------------------------------------------------
/packages/website/public/images/logo-readme-dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/frontend-challenges/81bd0e5a3b27fc84925a7ad431f12c973e81c9c6/packages/website/public/images/logo-readme-dark.png
--------------------------------------------------------------------------------
/packages/website/public/images/logo-readme-light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/frontend-challenges/81bd0e5a3b27fc84925a7ad431f12c973e81c9c6/packages/website/public/images/logo-readme-light.png
--------------------------------------------------------------------------------
/packages/website/public/images/logo.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/packages/website/public/og.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/frontend-challenges/81bd0e5a3b27fc84925a7ad431f12c973e81c9c6/packages/website/public/og.png
--------------------------------------------------------------------------------
/packages/website/public/questions/rtl-icon-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jsartisan/frontend-challenges/81bd0e5a3b27fc84925a7ad431f12c973e81c9c6/packages/website/public/questions/rtl-icon-1.png
--------------------------------------------------------------------------------
/packages/website/public/robots.txt:
--------------------------------------------------------------------------------
1 | # Allow all crawlers
2 | User-agent: *
3 | Allow: /
--------------------------------------------------------------------------------
/packages/website/store/ui.ts:
--------------------------------------------------------------------------------
1 | import { create } from "zustand";
2 |
3 | type UiStore = {
4 | isLoginModalOpen: boolean;
5 | toggleLoginModal: (shouldOpen: boolean) => void;
6 | };
7 |
8 | export const useUiStore = create((set) => ({
9 | isLoginModalOpen: false,
10 | toggleLoginModal: (shouldOpen) => set({ isLoginModalOpen: shouldOpen }),
11 | }));
12 |
--------------------------------------------------------------------------------
/packages/website/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": false,
8 | "noEmit": true,
9 | "incremental": true,
10 | "module": "esnext",
11 | "esModuleInterop": true,
12 | "moduleResolution": "node",
13 | "resolveJsonModule": true,
14 | "isolatedModules": true,
15 | "noImplicitAny": false,
16 | "jsx": "preserve",
17 | "plugins": [
18 | {
19 | "name": "next"
20 | }
21 | ],
22 | "target": "ES2017"
23 | },
24 | "exclude": ["node_modules"],
25 | "include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx", "../shared/src/utils/template.ts"]
26 | }
27 |
--------------------------------------------------------------------------------
/packages/website/utils/categories.ts:
--------------------------------------------------------------------------------
1 | import { CATEGORIES, Challenge } from "@/shared";
2 |
3 | export function getCategoriesWithChallengesCount(challenges: Challenge[]) {
4 | return CATEGORIES.map((category) => ({
5 | name: category,
6 | challengesCount: challenges.filter((challenge) => challenge.category === category).length,
7 | }));
8 | }
9 |
--------------------------------------------------------------------------------
/packages/website/utils/helpers.ts:
--------------------------------------------------------------------------------
1 | import { twMerge } from "tailwind-merge";
2 | import { type ClassValue, clsx } from "clsx";
3 | import { Children, isValidElement } from "react";
4 |
5 | export function cn(...inputs: ClassValue[]) {
6 | return twMerge(clsx(inputs));
7 | }
8 |
9 | export function getValidChildren(children: React.ReactNode) {
10 | return Children.toArray(children).filter((child) => isValidElement(child)) as React.ReactElement[];
11 | }
12 |
13 | export const setLanguage = function (activeFile) {
14 | switch (activeFile.split(".").pop()) {
15 | case "js":
16 | return "javascript";
17 | case "jsx":
18 | return "javascript";
19 | case "ts":
20 | return "typescript";
21 | case "tsx":
22 | return "typescript";
23 | case "css":
24 | return "css";
25 | case "scss":
26 | return "scss";
27 | case "html":
28 | return "html";
29 | case "json":
30 | return "json";
31 | case "md":
32 | return "markdown";
33 | case "svelte":
34 | return "html";
35 | default:
36 | return "plaintext";
37 | }
38 | };
39 |
--------------------------------------------------------------------------------
/packages/website/utils/localStorage.ts:
--------------------------------------------------------------------------------
1 | export function getLocalStorageItem(key: string, defaultValue: any) {
2 | if (typeof window === "undefined") return defaultValue;
3 |
4 | const item = localStorage.getItem(key);
5 |
6 | if (!item) return defaultValue;
7 |
8 | try {
9 | return JSON.parse(item);
10 | } catch {
11 | return defaultValue;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/packages/website/utils/markdown.ts:
--------------------------------------------------------------------------------
1 | import { bundleMDX } from "mdx-bundler";
2 | import { visit } from "unist-util-visit";
3 |
4 | export const bundleMarkdown = async (source: string) => {
5 | return await bundleMDX({
6 | source: source,
7 | mdxOptions(options) {
8 | options.remarkPlugins = [...(options.remarkPlugins ?? [])];
9 | options.rehypePlugins = [
10 | ...(options.rehypePlugins ?? []),
11 | function rehypeMetaAsAttributes() {
12 | return (tree) => {
13 | visit(tree, "element", (node) => {
14 | if (node.tagName === "code" && node.data && node.data.meta) {
15 | node.properties.meta = node.data.meta;
16 | }
17 | });
18 | };
19 | },
20 | ];
21 |
22 | return options;
23 | },
24 | });
25 | };
26 |
--------------------------------------------------------------------------------
/packages/website/utils/mixpanel.ts:
--------------------------------------------------------------------------------
1 | import mixpanel from "mixpanel-browser";
2 |
3 | mixpanel.init(process.env.NEXT_PUBLIC_MIXPANEL_PROJECT_KEY);
4 |
5 | const env_check: any = process.env.NODE_ENV === "development";
6 |
7 | if (env_check) {
8 | mixpanel.identify = (id: any) => {
9 | console.log("mixpanel identify", id);
10 | };
11 |
12 | mixpanel.alias = (id: any) => {
13 | console.log("mixpanel alias", id);
14 | };
15 |
16 | mixpanel.track = (name: any, props: any) => {
17 | console.log("mixpanel track", name, props);
18 | };
19 |
20 | mixpanel.people = {
21 | ...mixpanel.people,
22 | set: (props: any) => {
23 | console.log("mixpanel people", props);
24 | },
25 | };
26 | }
27 |
28 | const actions = {
29 | identify: (id: any) => {
30 | mixpanel.identify(id);
31 | },
32 | alias: (id: any) => {
33 | mixpanel.alias(id);
34 | },
35 | track: (name: any, props: any) => {
36 | mixpanel?.track(name, props);
37 | },
38 | people: {
39 | set: (props: any) => {
40 | mixpanel.people.set(props);
41 | },
42 | },
43 | };
44 |
45 | export { actions as mixpanel };
46 |
--------------------------------------------------------------------------------
/packages/website/utils/sessionStorage.ts:
--------------------------------------------------------------------------------
1 | export function getSessionStorageItem(key: string, defaultValue: any) {
2 | if (typeof window === "undefined") {
3 | return defaultValue;
4 | }
5 |
6 | const item = sessionStorage.getItem(key);
7 |
8 | if (!item) {
9 | return defaultValue;
10 | }
11 |
12 | try {
13 | return JSON.parse(item);
14 | } catch {
15 | return defaultValue;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/packages/website/utils/supabase/client.ts:
--------------------------------------------------------------------------------
1 | import { createBrowserClient } from "@supabase/ssr";
2 |
3 | export function createClient() {
4 | return createBrowserClient(process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!);
5 | }
6 |
7 | export const supabase = createClient();
8 |
--------------------------------------------------------------------------------
/packages/website/utils/supabase/server.ts:
--------------------------------------------------------------------------------
1 | import { createServerClient } from "@supabase/ssr";
2 | import { cookies } from "next/headers";
3 |
4 | export function createClient() {
5 | const cookieStore = cookies();
6 |
7 | return createServerClient(process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!, {
8 | cookies: {
9 | getAll() {
10 | return cookieStore.getAll();
11 | },
12 | setAll(cookiesToSet) {
13 | try {
14 | cookiesToSet.forEach(({ name, value, options }) => cookieStore.set(name, value, options));
15 | } catch {
16 | // The `setAll` method was called from a Server Component.
17 | // This can be ignored if you have middleware refreshing
18 | // user sessions.
19 | }
20 | },
21 | },
22 | });
23 | }
24 |
--------------------------------------------------------------------------------
/pnpm-workspace.yaml:
--------------------------------------------------------------------------------
1 | packages:
2 | - packages/**
--------------------------------------------------------------------------------
/roadmaps/javascript/info.yml:
--------------------------------------------------------------------------------
1 | title: JavaScript
2 | description: Challenges includes basic to advanced JavaScript concepts, including ES6, Objects, Arrays, Functions, and more.
3 | topics:
4 | - title: "Objects"
5 | challenges:
6 | - 66-this
7 | - 69-two-functions-one-object
8 | - title: "Data Types"
9 | challenges:
10 | - 18-flatten
11 | - title: "Advanced Functions"
12 | challenges:
13 | - 99-closure-2
14 | - 109-jest-spyon
15 | - 121-f-prototype
16 | - title: "Promises"
17 | challenges:
18 | - 35-promise-all
19 | - 37-promise-race
20 | - 43-promise-any
21 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "lib": ["dom", "dom.iterable", "esnext"],
4 | "allowJs": true,
5 | "skipLibCheck": true,
6 | "strict": false,
7 | "noEmit": true,
8 | "incremental": true,
9 | "module": "esnext",
10 | "esModuleInterop": true,
11 | "moduleResolution": "node",
12 | "resolveJsonModule": true,
13 | "isolatedModules": true,
14 | "noImplicitAny": false,
15 | "jsx": "preserve",
16 | "baseUrl": "."
17 | },
18 | "exclude": ["node_modules"],
19 | "include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx"]
20 | }
21 |
--------------------------------------------------------------------------------