[web] interviews/focus-areas: remove focus areas unnecessary data files and use the data from the contentlayer (#901)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
parent
d219fa1d3b
commit
ea6cb60aed
|
|
@ -13,12 +13,11 @@ import {
|
|||
|
||||
import { trpc } from '~/hooks/trpc';
|
||||
|
||||
import {
|
||||
categorizeFocusAreas_DEPRECATED,
|
||||
getFocusAreaTheme_DEPRECATED,
|
||||
} from '~/data/focus-areas/FocusAreas';
|
||||
|
||||
import InterviewsListPageHeader from '~/components/interviews/common/InterviewsListPageHeader';
|
||||
import {
|
||||
categorizeFocusAreas,
|
||||
FocusAreaIcons,
|
||||
} from '~/components/interviews/questions/content/study-list/FocusAreas';
|
||||
import InterviewsStudyListCard from '~/components/interviews/questions/listings/learning/InterviewsStudyListCard';
|
||||
import { useIntl } from '~/components/intl';
|
||||
import MDXContent from '~/components/mdx/MDXContent';
|
||||
|
|
@ -47,7 +46,7 @@ export default function InterviewsRevampFocusAreaListPage({
|
|||
});
|
||||
|
||||
const sessions = questionListSessions ?? [];
|
||||
const focusAreasCategories = categorizeFocusAreas_DEPRECATED(intl);
|
||||
const focusAreasCategories = categorizeFocusAreas(intl, focusAreas);
|
||||
|
||||
const features = [
|
||||
{
|
||||
|
|
@ -123,18 +122,17 @@ export default function InterviewsRevampFocusAreaListPage({
|
|||
<div className="flex flex-col gap-4">
|
||||
{items.map((focusArea) => {
|
||||
const session = sessions.find(
|
||||
(session_) => session_.key === focusArea.type,
|
||||
(session_) => session_.key === focusArea.slug,
|
||||
);
|
||||
const completionCount = session?._count.progress;
|
||||
const theme = getFocusAreaTheme_DEPRECATED(focusArea.type);
|
||||
|
||||
return (
|
||||
<InterviewsStudyListCard
|
||||
key={focusArea.type}
|
||||
key={focusArea.slug}
|
||||
completionCount={completionCount}
|
||||
icon={FocusAreaIcons[focusArea.slug]}
|
||||
isStarted={session != null}
|
||||
metadata={focusArea}
|
||||
theme={theme}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
|
|
|||
|
|
@ -14,17 +14,14 @@ import {
|
|||
|
||||
import { trpc } from '~/hooks/trpc';
|
||||
|
||||
import { INTERVIEWS_REVAMP_2024 } from '~/data/FeatureFlags';
|
||||
import { getFocusAreaTheme_DEPRECATED } from '~/data/focus-areas/FocusAreas';
|
||||
|
||||
import type {
|
||||
QuestionFormat,
|
||||
QuestionMetadata,
|
||||
QuestionSlug,
|
||||
} from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import { FocusAreaIcons } from '~/components/interviews/questions/content/study-list/FocusAreas';
|
||||
import QuestionsLearningList from '~/components/interviews/questions/listings/learning/QuestionsStudyList';
|
||||
import QuestionsLearningListPageTitleSection from '~/components/interviews/questions/listings/learning/QuestionsStudyListPageTitleSection';
|
||||
import QuestionsStudyListTitleSection_DEPRECATED from '~/components/interviews/questions/listings/learning/QuestionsStudyListTitleSection_DEPRECATED';
|
||||
import { useIntl } from '~/components/intl';
|
||||
import MDXContent from '~/components/mdx/MDXContent';
|
||||
import Button from '~/components/ui/Button';
|
||||
|
|
@ -70,7 +67,6 @@ export default function InterviewsFocusAreaPage({
|
|||
questionsProgressAll,
|
||||
questionsSlugs,
|
||||
);
|
||||
const focusAreaTheme = getFocusAreaTheme_DEPRECATED(focusArea.slug);
|
||||
const questionCount = countNumberOfQuestionsInList(questionsSlugs);
|
||||
|
||||
const features = [
|
||||
|
|
@ -122,33 +118,16 @@ export default function InterviewsFocusAreaPage({
|
|||
variant="tertiary"
|
||||
/>
|
||||
</div>
|
||||
{INTERVIEWS_REVAMP_2024 ? (
|
||||
<>
|
||||
<QuestionsLearningListPageTitleSection
|
||||
description={focusArea.description}
|
||||
features={features}
|
||||
icon={focusAreaTheme.iconOutline}
|
||||
overallProgress={questionProgressParam ?? []}
|
||||
questions={flattenQuestionFormatMetadata(questionsMetadata)}
|
||||
questionsSessionKey={focusArea.type}
|
||||
themeBackgroundClass={focusAreaTheme.gradient.className}
|
||||
title={focusArea.longName}
|
||||
/>
|
||||
<Divider />
|
||||
</>
|
||||
) : (
|
||||
<QuestionsStudyListTitleSection_DEPRECATED
|
||||
description={focusArea.description}
|
||||
icon={focusAreaTheme.iconOutline}
|
||||
overallProgress={questionProgressParam ?? []}
|
||||
progressTrackingAvailableToNonPremiumUsers={true}
|
||||
questionCount={questionCount}
|
||||
questionListKey={focusArea.type}
|
||||
questions={flattenQuestionFormatMetadata(questionsMetadata)}
|
||||
themeBackgroundClass={focusAreaTheme.gradient.className}
|
||||
title={focusArea.longName}
|
||||
/>
|
||||
)}
|
||||
<QuestionsLearningListPageTitleSection
|
||||
description={focusArea.description}
|
||||
features={features}
|
||||
icon={FocusAreaIcons[focusArea.type]}
|
||||
overallProgress={questionProgressParam ?? []}
|
||||
questions={flattenQuestionFormatMetadata(questionsMetadata)}
|
||||
questionsSessionKey={focusArea.type}
|
||||
title={focusArea.longName}
|
||||
/>
|
||||
<Divider />
|
||||
</div>
|
||||
<Section>
|
||||
<QuestionsLearningList
|
||||
|
|
|
|||
|
|
@ -133,7 +133,6 @@ export default function InterviewsBlind75Page({
|
|||
...systemDesignQuestions,
|
||||
]}
|
||||
questionsSessionKey="blind75"
|
||||
themeBackgroundClass={planTheme.gradient.className}
|
||||
title={plan.name}
|
||||
/>
|
||||
</Container>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import { trpc } from '~/hooks/trpc';
|
|||
|
||||
import PreparationGFE75Logo from '~/data/plans/logo/PreparationGFE75Logo';
|
||||
import type { PreparationPlan } from '~/data/plans/PreparationPlans';
|
||||
import { getPreparationPlanTheme } from '~/data/plans/PreparationPlans';
|
||||
|
||||
import FeedbackDialog from '~/components/global/feedback/FeedbackDialog';
|
||||
import { useUserPreferences } from '~/components/global/UserPreferencesProvider';
|
||||
|
|
@ -72,8 +71,6 @@ export default function InterviewsGFE75Page({
|
|||
plan.questions,
|
||||
);
|
||||
|
||||
const planTheme = getPreparationPlanTheme(plan.type);
|
||||
|
||||
const features = [
|
||||
{
|
||||
icon: RiWindowLine,
|
||||
|
|
@ -147,7 +144,6 @@ export default function InterviewsGFE75Page({
|
|||
...systemDesignQuestions,
|
||||
]}
|
||||
questionsSessionKey="greatfrontend75"
|
||||
themeBackgroundClass={planTheme.gradient.className}
|
||||
title={plan.name}
|
||||
/>
|
||||
</Container>
|
||||
|
|
|
|||
|
|
@ -11,20 +11,15 @@ import {
|
|||
|
||||
import { trpc } from '~/hooks/trpc';
|
||||
|
||||
import { INTERVIEWS_REVAMP_2024 } from '~/data/FeatureFlags';
|
||||
import type { PreparationPlan } from '~/data/plans/PreparationPlans';
|
||||
import { getPreparationPlanTheme } from '~/data/plans/PreparationPlans';
|
||||
|
||||
import { useUserProfile } from '~/components/global/UserProfileProvider';
|
||||
import QuestionPaywall from '~/components/interviews/questions/common/QuestionPaywall';
|
||||
import type {
|
||||
QuestionDifficulty,
|
||||
QuestionMetadata,
|
||||
} from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import type { QuestionMetadata } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import QuestionsList from '~/components/interviews/questions/listings/items/QuestionsList';
|
||||
import QuestionsLearningList from '~/components/interviews/questions/listings/learning/QuestionsStudyList';
|
||||
import QuestionsLearningListPageTitleSection from '~/components/interviews/questions/listings/learning/QuestionsStudyListPageTitleSection';
|
||||
import QuestionsStudyListTitleSection_DEPRECATED from '~/components/interviews/questions/listings/learning/QuestionsStudyListTitleSection_DEPRECATED';
|
||||
import { useIntl } from '~/components/intl';
|
||||
import MDXContent from '~/components/mdx/MDXContent';
|
||||
import Button from '~/components/ui/Button';
|
||||
|
|
@ -43,14 +38,12 @@ import { useUser } from '@supabase/auth-helpers-react';
|
|||
type Props = Readonly<{
|
||||
bottomContent?: InterviewsListingBottomContent;
|
||||
codingQuestions: ReadonlyArray<QuestionMetadata>;
|
||||
difficultySummary: Record<QuestionDifficulty, number>;
|
||||
plan: PreparationPlan;
|
||||
quizQuestions: ReadonlyArray<QuestionMetadata>;
|
||||
systemDesignQuestions: ReadonlyArray<QuestionMetadata>;
|
||||
}>;
|
||||
|
||||
export default function InterviewsStudyPlanPage({
|
||||
difficultySummary,
|
||||
quizQuestions,
|
||||
codingQuestions,
|
||||
systemDesignQuestions,
|
||||
|
|
@ -127,44 +120,21 @@ export default function InterviewsStudyPlanPage({
|
|||
variant="tertiary"
|
||||
/>
|
||||
</div>
|
||||
{INTERVIEWS_REVAMP_2024 ? (
|
||||
<>
|
||||
<QuestionsLearningListPageTitleSection
|
||||
description={plan.description}
|
||||
feature="study-plans"
|
||||
features={features}
|
||||
icon={planTheme.iconOutline}
|
||||
overallProgress={questionProgressParam ?? []}
|
||||
questions={[
|
||||
...quizQuestions,
|
||||
...codingQuestions,
|
||||
...systemDesignQuestions,
|
||||
]}
|
||||
questionsSessionKey={plan.type}
|
||||
themeBackgroundClass={planTheme.gradient.className}
|
||||
title={plan.longName}
|
||||
/>
|
||||
<Divider />
|
||||
</>
|
||||
) : (
|
||||
<QuestionsStudyListTitleSection_DEPRECATED
|
||||
description={plan.description}
|
||||
difficultySummary={difficultySummary}
|
||||
feature="study-plans"
|
||||
icon={planTheme.iconOutline}
|
||||
overallProgress={questionProgressParam ?? []}
|
||||
questionCount={questionCount}
|
||||
questionListKey={plan.type}
|
||||
questions={[
|
||||
...quizQuestions,
|
||||
...codingQuestions,
|
||||
...systemDesignQuestions,
|
||||
]}
|
||||
schedule={plan.schedule}
|
||||
themeBackgroundClass={planTheme.gradient.className}
|
||||
title={plan.longName}
|
||||
/>
|
||||
)}
|
||||
<QuestionsLearningListPageTitleSection
|
||||
description={plan.description}
|
||||
feature="study-plans"
|
||||
features={features}
|
||||
icon={planTheme.iconOutline}
|
||||
overallProgress={questionProgressParam ?? []}
|
||||
questions={[
|
||||
...quizQuestions,
|
||||
...codingQuestions,
|
||||
...systemDesignQuestions,
|
||||
]}
|
||||
questionsSessionKey={plan.type}
|
||||
title={plan.longName}
|
||||
/>
|
||||
<Divider />
|
||||
</div>
|
||||
<Section>
|
||||
<div>
|
||||
|
|
|
|||
|
|
@ -7,10 +7,7 @@ import type { PreparationPlanType } from '~/data/plans/PreparationPlans';
|
|||
import { getPreparationPlan } from '~/data/plans/PreparationPlans';
|
||||
|
||||
import type { QuestionMetadata } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import {
|
||||
countQuestionsByDifficulty,
|
||||
sortQuestions,
|
||||
} from '~/components/interviews/questions/listings/filters/QuestionsProcessor';
|
||||
import { sortQuestions } from '~/components/interviews/questions/listings/filters/QuestionsProcessor';
|
||||
|
||||
import { fetchInterviewListingBottomContent } from '~/db/contentlayer/InterviewsListingBottomContentReader';
|
||||
import { fetchPreparationPlans } from '~/db/PreparationPlansReader';
|
||||
|
|
@ -90,10 +87,6 @@ export default async function Page({ params }: Props) {
|
|||
const systemDesignQuestionsForPlan = questions['system-design'];
|
||||
const quizQuestionsForPlan =
|
||||
questions.quiz as ReadonlyArray<QuestionMetadata>;
|
||||
const difficultySummary = countQuestionsByDifficulty([
|
||||
...codingQuestionsForPlan,
|
||||
...systemDesignQuestionsForPlan,
|
||||
]);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
@ -111,7 +104,6 @@ export default async function Page({ params }: Props) {
|
|||
INTERVIEWS_REVAMP_BOTTOM_CONTENT ? bottomContent : undefined
|
||||
}
|
||||
codingQuestions={codingQuestionsForPlan}
|
||||
difficultySummary={difficultySummary}
|
||||
plan={preparationPlan}
|
||||
quizQuestions={sortQuestions(quizQuestionsForPlan, 'importance', false)}
|
||||
systemDesignQuestions={systemDesignQuestionsForPlan}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import { RiListCheck3, RiTimerLine, RiVerifiedBadgeLine } from 'react-icons/ri';
|
|||
import { trpc } from '~/hooks/trpc';
|
||||
|
||||
import {
|
||||
getPreparationPlanTheme,
|
||||
type PreparationPlan,
|
||||
type PreparationPlans,
|
||||
} from '~/data/plans/PreparationPlans';
|
||||
|
|
@ -115,7 +114,6 @@ export default function InterviewsRevampStudyPlansPage({
|
|||
(session_) => session_.key === studyPlan.type,
|
||||
);
|
||||
const completionCount = session?._count.progress;
|
||||
const theme = getPreparationPlanTheme(studyPlan.type);
|
||||
|
||||
return (
|
||||
<InterviewsStudyListCard
|
||||
|
|
@ -124,7 +122,7 @@ export default function InterviewsRevampStudyPlansPage({
|
|||
isStarted={session != null}
|
||||
metadata={studyPlan}
|
||||
schedule={studyPlan.schedule}
|
||||
theme={theme}
|
||||
// TODO(interviews): need to pass icon
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ export default async function Page({ params }: Props) {
|
|||
{ questions: systemDesignQuestions },
|
||||
bottomContent,
|
||||
companyGuides,
|
||||
focusAreas,
|
||||
] = await Promise.all([
|
||||
await fetchPreparationPlans(intl as IntlShape),
|
||||
fetchQuestionsListQuiz(locale),
|
||||
|
|
@ -66,6 +67,7 @@ export default async function Page({ params }: Props) {
|
|||
fetchQuestionsListSystemDesign(locale),
|
||||
fetchInterviewListingBottomContent('dashboard'),
|
||||
fetchInterviewsStudyLists('company'),
|
||||
fetchInterviewsStudyLists('focus-area'),
|
||||
]);
|
||||
const { framework, language } = categorizeQuestionsByFrameworkAndLanguage({
|
||||
codingQuestions,
|
||||
|
|
@ -81,6 +83,7 @@ export default async function Page({ params }: Props) {
|
|||
INTERVIEWS_REVAMP_BOTTOM_CONTENT ? bottomContent : undefined
|
||||
}
|
||||
companyGuides={sortedGuides}
|
||||
focusAreas={focusAreas}
|
||||
preparationPlans={preparationPlans}
|
||||
questions={{
|
||||
codingQuestions,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import InterviewsDashboardLayout from '~/components/interviews/dashboard/InterviewsDashboardLayout';
|
||||
|
||||
import { fetchInterviewsStudyLists } from '~/db/contentlayer/InterviewsStudyListReader';
|
||||
import { fetchQuestionsListCount } from '~/db/QuestionsListReader';
|
||||
|
||||
type Props = Readonly<{
|
||||
|
|
@ -7,12 +8,14 @@ type Props = Readonly<{
|
|||
}>;
|
||||
|
||||
export default async function DashboardPageLayout({ children }: Props) {
|
||||
const [questionTotalAvailableCount] = await Promise.all([
|
||||
const [questionTotalAvailableCount, focusAreas] = await Promise.all([
|
||||
fetchQuestionsListCount(),
|
||||
fetchInterviewsStudyLists('focus-area'),
|
||||
]);
|
||||
|
||||
return (
|
||||
<InterviewsDashboardLayout
|
||||
focusAreas={focusAreas}
|
||||
questionTotalAvailableCount={questionTotalAvailableCount}>
|
||||
{children}
|
||||
</InterviewsDashboardLayout>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import {
|
|||
RiQuestionnaireLine,
|
||||
RiShieldKeyholeLine,
|
||||
} from 'react-icons/ri';
|
||||
import { TbBinaryTree } from 'react-icons/tb';
|
||||
|
||||
import InterviewsGitHubSlider from '~/components/interviews/common/github/InterviewsGitHubSlider';
|
||||
import InterviewsDashboardContinueLearning from '~/components/interviews/dashboard/InterviewsDashboardContinueLearning';
|
||||
|
|
@ -21,7 +20,6 @@ import InterviewsMarketingQuestionCardMarquee from '~/components/interviews/mark
|
|||
import InterviewsPaymentFailureDialog from '~/components/interviews/purchase/InterviewsPaymentFailureDialog';
|
||||
import type { QuestionMetadata } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import QuestionListingTopicFilters from '~/components/interviews/questions/listings/filters/QuestionListingTopicFilters';
|
||||
import QuestionsStudyListTitleSection_DEPRECATED from '~/components/interviews/questions/listings/learning/QuestionsStudyListTitleSection_DEPRECATED';
|
||||
import QuestionListingDifficultySummary from '~/components/interviews/questions/listings/stats/QuestionListingDifficultySummary';
|
||||
import QuestionsProgressPanel from '~/components/interviews/questions/listings/stats/QuestionsProgressPanel';
|
||||
import QuestionCountLabel from '~/components/interviews/questions/metadata/QuestionCountLabel';
|
||||
|
|
@ -337,7 +335,6 @@ export default function ScrapbookPage() {
|
|||
{
|
||||
completedCount: 30,
|
||||
durationMins: 92,
|
||||
gradient: themeGradientPurpleGreen,
|
||||
href: '/dev__/scrapbook?plan=algo',
|
||||
questionsCount: 47,
|
||||
reverseGradient: true,
|
||||
|
|
@ -346,7 +343,6 @@ export default function ScrapbookPage() {
|
|||
{
|
||||
completedCount: 25,
|
||||
durationMins: 92,
|
||||
gradient: themeGradientGreenYellow,
|
||||
href: '/dev__/scrapbook?plan=forms',
|
||||
questionsCount: 47,
|
||||
reverseGradient: true,
|
||||
|
|
@ -355,7 +351,6 @@ export default function ScrapbookPage() {
|
|||
{
|
||||
completedCount: 15,
|
||||
durationMins: 92,
|
||||
gradient: themeGradientPinkPurple,
|
||||
href: '/dev__/scrapbook?plan=accessibility',
|
||||
questionsCount: 47,
|
||||
title: 'Accessibility',
|
||||
|
|
@ -366,29 +361,6 @@ export default function ScrapbookPage() {
|
|||
</UIExamplesGroup>
|
||||
</div>
|
||||
</Section>
|
||||
<Container>
|
||||
<Heading level="heading3">Study Plans / Focus Areas</Heading>
|
||||
</Container>
|
||||
<Section>
|
||||
<div>
|
||||
<UIExamplesGroup>
|
||||
<QuestionsStudyListTitleSection_DEPRECATED
|
||||
difficultySummary={{
|
||||
easy: 30,
|
||||
hard: 10,
|
||||
medium: 20,
|
||||
}}
|
||||
icon={TbBinaryTree}
|
||||
overallProgress={[]}
|
||||
questionCount={47}
|
||||
questionListKey="one-month"
|
||||
questions={[]}
|
||||
themeBackgroundClass={themeGradientPurpleGreen.className}
|
||||
title="Data structure and algorithms"
|
||||
/>
|
||||
</UIExamplesGroup>
|
||||
</div>
|
||||
</Section>
|
||||
<Container>
|
||||
<Heading level="heading3">Marketing</Heading>
|
||||
</Container>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import type {
|
|||
import { useMemo } from 'react';
|
||||
import {
|
||||
RiArrowLeftLine,
|
||||
RiGoogleFill,
|
||||
RiQuestionnaireLine,
|
||||
RiThumbUpLine,
|
||||
RiVerifiedBadgeLine,
|
||||
|
|
@ -29,7 +28,6 @@ import type {
|
|||
import QuestionsList from '~/components/interviews/questions/listings/items/QuestionsList';
|
||||
import QuestionsLearningList from '~/components/interviews/questions/listings/learning/QuestionsStudyList';
|
||||
import QuestionsLearningListPageTitleSection from '~/components/interviews/questions/listings/learning/QuestionsStudyListPageTitleSection';
|
||||
import QuestionsStudyListTitleSection_DEPRECATED from '~/components/interviews/questions/listings/learning/QuestionsStudyListTitleSection_DEPRECATED';
|
||||
import { useIntl } from '~/components/intl';
|
||||
import MDXContent from '~/components/mdx/MDXContent';
|
||||
import Button from '~/components/ui/Button';
|
||||
|
|
@ -37,7 +35,6 @@ import Container from '~/components/ui/Container';
|
|||
import Divider from '~/components/ui/Divider';
|
||||
import Heading from '~/components/ui/Heading';
|
||||
import Section from '~/components/ui/Heading/HeadingContext';
|
||||
import { themeGradientGreenYellow } from '~/components/ui/theme';
|
||||
|
||||
import {
|
||||
categorizeQuestionsProgress,
|
||||
|
|
@ -169,54 +166,31 @@ export default function InterviewsCompanyGuidePage({
|
|||
variant="tertiary"
|
||||
/>
|
||||
</div>
|
||||
{INTERVIEWS_REVAMP_2024 ? (
|
||||
<>
|
||||
<QuestionsLearningListPageTitleSection
|
||||
description={companyGuide.shortDescription}
|
||||
feature="company-guides"
|
||||
features={features}
|
||||
logoImgSrc={companyGuide.logoUrl}
|
||||
overallProgress={questionProgressParam ?? []}
|
||||
questions={questions}
|
||||
questionsSessionKey={companyGuide.slug}
|
||||
themeBackgroundClass={themeGradientGreenYellow.className}
|
||||
title={intl.formatMessage(
|
||||
{
|
||||
defaultMessage: '{company} Front End Interview Guide',
|
||||
description: 'Title for company guides detail page',
|
||||
id: 'SaUyXa',
|
||||
},
|
||||
{
|
||||
company: companyGuide.name,
|
||||
},
|
||||
)}
|
||||
/>
|
||||
<Divider />
|
||||
{/* Insider tips */}
|
||||
{insiderTipsData.length > 0 && (
|
||||
<div className="max-w-2xl">
|
||||
<InterviewsCompanyInsiderTipsSlider data={insiderTipsData} />
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<QuestionsStudyListTitleSection_DEPRECATED
|
||||
description={<MDXContent mdxCode={companyGuide.body.code} />}
|
||||
feature="company-guides"
|
||||
icon={({ className, ...props }) => (
|
||||
<RiGoogleFill
|
||||
className={clsx('text-neutral-900', className)}
|
||||
{...props}
|
||||
/>
|
||||
)}
|
||||
logoImgSrc={companyGuide.logoUrl}
|
||||
overallProgress={questionProgressParam ?? []}
|
||||
questionCount={questionCount}
|
||||
questionListKey={companyGuide.slug}
|
||||
questions={questions}
|
||||
themeBackgroundClass={clsx('bg-white', 'shadow-md')}
|
||||
title={`${companyGuide.name} Front End Engineer Interview Questions and Guides`}
|
||||
/>
|
||||
<QuestionsLearningListPageTitleSection
|
||||
description={companyGuide.shortDescription}
|
||||
feature="company-guides"
|
||||
features={features}
|
||||
logoImgSrc={companyGuide.logoUrl}
|
||||
overallProgress={questionProgressParam ?? []}
|
||||
questions={questions}
|
||||
questionsSessionKey={companyGuide.slug}
|
||||
title={intl.formatMessage(
|
||||
{
|
||||
defaultMessage: '{company} Front End Interview Guide',
|
||||
description: 'Title for company guides detail page',
|
||||
id: 'SaUyXa',
|
||||
},
|
||||
{
|
||||
company: companyGuide.name,
|
||||
},
|
||||
)}
|
||||
/>
|
||||
<Divider />
|
||||
{/* Insider tips */}
|
||||
{insiderTipsData.length > 0 && (
|
||||
<div className="max-w-2xl">
|
||||
<InterviewsCompanyInsiderTipsSlider data={insiderTipsData} />
|
||||
</div>
|
||||
)}
|
||||
</Container>
|
||||
<Section>
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
import clsx from 'clsx';
|
||||
|
||||
import getProgressBarGradient from '~/components/interviews/common/utils';
|
||||
import { FormattedMessage } from '~/components/intl';
|
||||
import Button from '~/components/ui/Button';
|
||||
import GradientProgressBar from '~/components/ui/GradientProgressBar/GradientProgressBar';
|
||||
import Heading from '~/components/ui/Heading';
|
||||
import Text from '~/components/ui/Text';
|
||||
import type { ThemeGradient } from '~/components/ui/theme';
|
||||
import {
|
||||
themeBackgroundCardWhiteOnLightColor,
|
||||
themeBorderColor,
|
||||
|
|
@ -22,7 +22,6 @@ type Props = Readonly<{
|
|||
items: ReadonlyArray<{
|
||||
completedCount: number;
|
||||
durationMins?: number;
|
||||
gradient: ThemeGradient;
|
||||
// Resume button leads here.
|
||||
href: string;
|
||||
questionsCount: number;
|
||||
|
|
@ -57,13 +56,13 @@ export default function InterviewsDashboardContinueLearning({
|
|||
({
|
||||
completedCount,
|
||||
durationMins,
|
||||
gradient,
|
||||
href,
|
||||
reverseGradient = false,
|
||||
title,
|
||||
questionsCount,
|
||||
}) => {
|
||||
const progressPercentage = (completedCount / questionsCount) * 100;
|
||||
const progressPercentage =
|
||||
Math.min(completedCount / Math.max(questionsCount, 1), 1) * 100;
|
||||
|
||||
return (
|
||||
<div
|
||||
|
|
@ -75,7 +74,10 @@ export default function InterviewsDashboardContinueLearning({
|
|||
<div className="flex items-center gap-4">
|
||||
<GradientProgressBar
|
||||
className="size-14"
|
||||
gradient={gradient}
|
||||
gradient={getProgressBarGradient({
|
||||
total: questionsCount,
|
||||
value: completedCount,
|
||||
})}
|
||||
progressPercentage={progressPercentage}
|
||||
reverseGradient={reverseGradient}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
import {
|
||||
getQuestionListThemes,
|
||||
useQuestionLists_DEPRECATED,
|
||||
} from '~/data/question-lists/QuestionListsHooks';
|
||||
import type { InterviewsStudyList } from 'contentlayer/generated';
|
||||
|
||||
import { usePreparationPlans } from '~/data/plans/PreparationPlansHooks';
|
||||
|
||||
import InterviewsDashboardContinueLearning from '~/components/interviews/dashboard/InterviewsDashboardContinueLearning';
|
||||
|
||||
import { countNumberOfQuestionsInList } from '~/db/QuestionsUtils';
|
||||
import { mapFocusAreasBySlug } from '../questions/content/study-list/FocusAreas';
|
||||
|
||||
type Props = Readonly<{
|
||||
focusAreas: ReadonlyArray<InterviewsStudyList>;
|
||||
items: ReadonlyArray<{
|
||||
completedCount: number;
|
||||
listKey: string;
|
||||
|
|
@ -16,24 +16,43 @@ type Props = Readonly<{
|
|||
|
||||
export default function InterviewsDashboardContinueLearningContainer({
|
||||
items,
|
||||
focusAreas,
|
||||
}: Props) {
|
||||
const questionLists = useQuestionLists_DEPRECATED();
|
||||
const themes = getQuestionListThemes();
|
||||
// TODO(interviews): need to update once preparation plan is migrated to contentlayer
|
||||
const plans = usePreparationPlans() as unknown as Record<
|
||||
string,
|
||||
InterviewsStudyList
|
||||
>;
|
||||
|
||||
const mapFocusAreas = mapFocusAreasBySlug(focusAreas);
|
||||
const questionLists = { ...plans, ...mapFocusAreas };
|
||||
|
||||
return (
|
||||
<InterviewsDashboardContinueLearning
|
||||
items={items
|
||||
// TODO(interviews): filter out company lists for now because company list rendering is not yet supported on the dashboard.
|
||||
.filter(({ listKey }) => questionLists[listKey] != null)
|
||||
.map(({ listKey, completedCount }) => ({
|
||||
completedCount,
|
||||
gradient: themes[listKey].gradient,
|
||||
href: questionLists[listKey]?.href,
|
||||
questionsCount: countNumberOfQuestionsInList(
|
||||
questionLists[listKey].questions,
|
||||
),
|
||||
title: questionLists[listKey].longName,
|
||||
}))}
|
||||
.map(({ listKey, completedCount }) => {
|
||||
const {
|
||||
href,
|
||||
longName,
|
||||
questionsAlgo,
|
||||
questionsJavaScript,
|
||||
questionsQuiz,
|
||||
questionsSystemDesign,
|
||||
} = questionLists[listKey];
|
||||
|
||||
return {
|
||||
completedCount,
|
||||
href,
|
||||
questionsCount:
|
||||
(questionsAlgo?.length ?? 0) +
|
||||
(questionsJavaScript?.length ?? 0) +
|
||||
(questionsQuiz?.length ?? 0) +
|
||||
(questionsSystemDesign?.length ?? 0),
|
||||
title: longName,
|
||||
};
|
||||
})}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,8 +7,6 @@ import Text from '~/components/ui/Text';
|
|||
import {
|
||||
themeBackgroundCardColor,
|
||||
themeBackgroundElementEmphasizedStateColor_Hover,
|
||||
themeGradientGreenYellow,
|
||||
themeGradientPurpleGreen,
|
||||
themeTextBrandColor_GroupHover,
|
||||
} from '~/components/ui/theme';
|
||||
|
||||
|
|
@ -24,7 +22,6 @@ function MockContinueLearningCard() {
|
|||
{
|
||||
completedCount: 24,
|
||||
durationMins: 92,
|
||||
gradient: themeGradientPurpleGreen,
|
||||
href: '/dsa',
|
||||
questionsCount: 47,
|
||||
reverseGradient: true,
|
||||
|
|
@ -37,7 +34,6 @@ function MockContinueLearningCard() {
|
|||
{
|
||||
completedCount: 24,
|
||||
durationMins: 92,
|
||||
gradient: themeGradientGreenYellow,
|
||||
href: '/a11y',
|
||||
questionsCount: 50,
|
||||
reverseGradient: true,
|
||||
|
|
|
|||
|
|
@ -1,27 +1,30 @@
|
|||
import { useFocusAreas_DEPRECATED } from '~/data/focus-areas/FocusAreasHooks';
|
||||
import type { InterviewsStudyList } from 'contentlayer/generated';
|
||||
|
||||
import { useIntl } from '~/components/intl';
|
||||
|
||||
import DashboardFocusAreasSection from './InterviewsDashboardFocusAreasSection';
|
||||
import { mapFocusAreasBySlug } from '../questions/content/study-list/FocusAreas';
|
||||
|
||||
type Props = Readonly<{
|
||||
focusAreas: ReadonlyArray<InterviewsStudyList>;
|
||||
limit?: number;
|
||||
}>;
|
||||
|
||||
export default function InterviewsDashboardFeaturedFocusAreas({
|
||||
limit = Infinity,
|
||||
focusAreas,
|
||||
}: Props) {
|
||||
const intl = useIntl();
|
||||
const focusAreas = useFocusAreas_DEPRECATED();
|
||||
const mapFocusAreas = mapFocusAreasBySlug(focusAreas);
|
||||
const areas = [
|
||||
focusAreas['async-operations'],
|
||||
focusAreas['data-structures-algorithms'],
|
||||
focusAreas['design-system-components'],
|
||||
focusAreas.lodash,
|
||||
focusAreas['dom-manipulation'],
|
||||
focusAreas.accessibility,
|
||||
focusAreas['javascript-polyfills'],
|
||||
focusAreas.forms,
|
||||
mapFocusAreas['async-operations'],
|
||||
mapFocusAreas['data-structures-algorithms'],
|
||||
mapFocusAreas['design-system-components'],
|
||||
mapFocusAreas.lodash,
|
||||
mapFocusAreas['dom-manipulation'],
|
||||
mapFocusAreas.accessibility,
|
||||
mapFocusAreas['javascript-polyfills'],
|
||||
mapFocusAreas.forms,
|
||||
].slice(0, limit);
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
import clsx from 'clsx';
|
||||
import type { InterviewsStudyList } from 'contentlayer/generated';
|
||||
import { RiArrowRightLine, RiQuestionFill } from 'react-icons/ri';
|
||||
|
||||
import type { FocusArea_DEPRECATED } from '~/data/focus-areas/FocusAreas';
|
||||
import { getFocusAreaTheme_DEPRECATED } from '~/data/focus-areas/FocusAreas';
|
||||
|
||||
import { useIntl } from '~/components/intl';
|
||||
import Anchor from '~/components/ui/Anchor';
|
||||
import Button from '~/components/ui/Button';
|
||||
|
|
@ -19,13 +17,12 @@ import {
|
|||
} from '~/components/ui/theme';
|
||||
import Tooltip from '~/components/ui/Tooltip';
|
||||
|
||||
import { countNumberOfQuestionsInList } from '~/db/QuestionsUtils';
|
||||
|
||||
import { FocusAreaIcons } from '../questions/content/study-list/FocusAreas';
|
||||
import QuestionCountLabel from '../questions/metadata/QuestionCountLabel';
|
||||
|
||||
type Props = Readonly<{
|
||||
description: string;
|
||||
focusAreas: ReadonlyArray<FocusArea_DEPRECATED>;
|
||||
focusAreas: ReadonlyArray<InterviewsStudyList>;
|
||||
title: string;
|
||||
}>;
|
||||
|
||||
|
|
@ -64,54 +61,70 @@ export default function InterviewsDashboardFocusAreasSection({
|
|||
)}
|
||||
</div>
|
||||
<CardContainer className="@4xl:grid-cols-4 @md:grid-cols-2 grid grid-cols-1 grid-rows-1 gap-3 md:gap-4 lg:gap-6">
|
||||
{focusAreas.map(({ href, name, type, shortDescription, questions }) => {
|
||||
const Icon = getFocusAreaTheme_DEPRECATED(type).iconSolid;
|
||||
{focusAreas.map(
|
||||
({
|
||||
href,
|
||||
name,
|
||||
slug,
|
||||
shortDescription,
|
||||
questionsAlgo,
|
||||
questionsJavaScript,
|
||||
questionsSystemDesign,
|
||||
questionsQuiz,
|
||||
}) => {
|
||||
const Icon = FocusAreaIcons[slug];
|
||||
|
||||
return (
|
||||
<Anchor key={type} href={href} variant="unstyled">
|
||||
<Card
|
||||
className="group/card relative isolate flex flex-col items-start gap-3 p-4"
|
||||
padding={false}>
|
||||
<div className="flex justify-between self-stretch">
|
||||
<span
|
||||
className={clsx(
|
||||
'size-10 inline-flex items-center justify-center rounded-md',
|
||||
themeBackgroundChipColor,
|
||||
themeTextSecondaryColor,
|
||||
'border border-transparent transition',
|
||||
'group-hover/card:border-brand-dark group-hover/card:text-brand-dark',
|
||||
'dark:group-hover/card:border-brand dark:group-hover/card:text-brand',
|
||||
)}>
|
||||
<Icon aria-hidden={true} className="size-6" />
|
||||
</span>
|
||||
<Tooltip
|
||||
invert={true}
|
||||
label={
|
||||
<div className="flex flex-col gap-y-1.5 font-medium">
|
||||
{shortDescription}
|
||||
<Divider />
|
||||
<QuestionCountLabel
|
||||
count={countNumberOfQuestionsInList(questions)}
|
||||
showIcon={true}
|
||||
/>
|
||||
</div>
|
||||
}>
|
||||
<RiQuestionFill
|
||||
className={clsx('size-6', themeIconColor)}
|
||||
/>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<Text
|
||||
className="display w-full truncate"
|
||||
color="label"
|
||||
size="body1"
|
||||
weight="medium">
|
||||
{name}
|
||||
</Text>
|
||||
</Card>
|
||||
</Anchor>
|
||||
);
|
||||
})}
|
||||
return (
|
||||
<Anchor key={slug} href={href} variant="unstyled">
|
||||
<Card
|
||||
className="group/card relative isolate flex flex-col items-start gap-3 p-4"
|
||||
padding={false}>
|
||||
<div className="flex justify-between self-stretch">
|
||||
<span
|
||||
className={clsx(
|
||||
'size-10 inline-flex items-center justify-center rounded-md',
|
||||
themeBackgroundChipColor,
|
||||
themeTextSecondaryColor,
|
||||
'border border-transparent transition',
|
||||
'group-hover/card:border-brand-dark group-hover/card:text-brand-dark',
|
||||
'dark:group-hover/card:border-brand dark:group-hover/card:text-brand',
|
||||
)}>
|
||||
<Icon aria-hidden={true} className="size-6" />
|
||||
</span>
|
||||
<Tooltip
|
||||
invert={true}
|
||||
label={
|
||||
<div className="flex flex-col gap-y-1.5 font-medium">
|
||||
{shortDescription}
|
||||
<Divider />
|
||||
<QuestionCountLabel
|
||||
count={
|
||||
(questionsAlgo?.length ?? 0) +
|
||||
(questionsJavaScript?.length ?? 0) +
|
||||
(questionsQuiz?.length ?? 0) +
|
||||
(questionsSystemDesign?.length ?? 0)
|
||||
}
|
||||
showIcon={true}
|
||||
/>
|
||||
</div>
|
||||
}>
|
||||
<RiQuestionFill
|
||||
className={clsx('size-6', themeIconColor)}
|
||||
/>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<Text
|
||||
className="display w-full truncate"
|
||||
color="label"
|
||||
size="body1"
|
||||
weight="medium">
|
||||
{name}
|
||||
</Text>
|
||||
</Card>
|
||||
</Anchor>
|
||||
);
|
||||
},
|
||||
)}
|
||||
</CardContainer>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
'use client';
|
||||
|
||||
import clsx from 'clsx';
|
||||
import type { InterviewsStudyList } from 'contentlayer/generated';
|
||||
import { useSelectedLayoutSegment } from 'next/navigation';
|
||||
import type { ReactNode } from 'react';
|
||||
import { useEffect, useRef } from 'react';
|
||||
|
|
@ -27,12 +28,14 @@ import { useUser } from '@supabase/auth-helpers-react';
|
|||
|
||||
type Props = Readonly<{
|
||||
children: ReactNode;
|
||||
focusAreas: ReadonlyArray<InterviewsStudyList>;
|
||||
questionTotalAvailableCount: QuestionTotalAvailableCount;
|
||||
}>;
|
||||
|
||||
export default function InterviewsDashboardLayout({
|
||||
children,
|
||||
questionTotalAvailableCount,
|
||||
focusAreas,
|
||||
}: Props) {
|
||||
const { pathname } = useI18nPathname();
|
||||
const tabsRef = useRef<HTMLDivElement>(null);
|
||||
|
|
@ -96,6 +99,7 @@ export default function InterviewsDashboardLayout({
|
|||
)}>
|
||||
{showContinueLearning && questionListSessions != null && (
|
||||
<DashboardContinueLearningWithFetching
|
||||
focusAreas={focusAreas}
|
||||
items={questionListSessions.map((session) => ({
|
||||
completedCount: session._count.progress,
|
||||
listKey: session.key,
|
||||
|
|
@ -103,6 +107,7 @@ export default function InterviewsDashboardLayout({
|
|||
/>
|
||||
)}
|
||||
<InterviewsDashboardFeaturedFocusAreas
|
||||
focusAreas={focusAreas}
|
||||
limit={showContinueLearning ? 4 : 8}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,81 @@
|
|||
import type { InterviewsStudyList } from 'contentlayer/generated';
|
||||
import { BiUniversalAccess } from 'react-icons/bi';
|
||||
import {
|
||||
RiDashboardLine,
|
||||
RiFlowChart,
|
||||
RiJavascriptFill,
|
||||
RiRefreshLine,
|
||||
RiWindowFill,
|
||||
} from 'react-icons/ri';
|
||||
import { SiLodash } from 'react-icons/si';
|
||||
import { TbBinaryTree, TbForms } from 'react-icons/tb';
|
||||
import type { IntlShape } from 'react-intl';
|
||||
|
||||
export const FocusAreaIcons: Record<
|
||||
string,
|
||||
(props: React.ComponentProps<'svg'>) => JSX.Element
|
||||
> = {
|
||||
accessibility: BiUniversalAccess,
|
||||
'async-operations': RiRefreshLine,
|
||||
'data-structures-algorithms': TbBinaryTree,
|
||||
'design-system-components': RiDashboardLine,
|
||||
'dom-manipulation': RiWindowFill,
|
||||
forms: TbForms,
|
||||
'javascript-polyfills': RiJavascriptFill,
|
||||
lodash: SiLodash,
|
||||
'state-management': RiFlowChart,
|
||||
};
|
||||
|
||||
export function mapFocusAreasBySlug(
|
||||
focusAreas: ReadonlyArray<InterviewsStudyList>,
|
||||
) {
|
||||
return focusAreas.reduce((acc: Record<string, InterviewsStudyList>, item) => {
|
||||
acc[item.slug] = item;
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
||||
|
||||
export function categorizeFocusAreas(
|
||||
intl: IntlShape,
|
||||
focusAreas: ReadonlyArray<InterviewsStudyList>,
|
||||
) {
|
||||
const mapFocusAreas = mapFocusAreasBySlug(focusAreas);
|
||||
|
||||
return [
|
||||
{
|
||||
items: [
|
||||
mapFocusAreas['javascript-polyfills'],
|
||||
mapFocusAreas['async-operations'],
|
||||
mapFocusAreas.lodash,
|
||||
],
|
||||
title: intl.formatMessage({
|
||||
defaultMessage: 'JavaScript Engineering',
|
||||
description: 'Title for focus area type',
|
||||
id: 'er249T',
|
||||
}),
|
||||
},
|
||||
{
|
||||
items: [
|
||||
mapFocusAreas['dom-manipulation'],
|
||||
mapFocusAreas.forms,
|
||||
mapFocusAreas['design-system-components'],
|
||||
mapFocusAreas.accessibility,
|
||||
mapFocusAreas['state-management'],
|
||||
],
|
||||
title: intl.formatMessage({
|
||||
defaultMessage: 'User Interface Development',
|
||||
description: 'Title for focus area type',
|
||||
id: '2M6LN4',
|
||||
}),
|
||||
},
|
||||
{
|
||||
items: [mapFocusAreas['data-structures-algorithms']],
|
||||
title: intl.formatMessage({
|
||||
defaultMessage: 'Computer Science Foundations',
|
||||
description: 'Title for focus area type',
|
||||
id: 'L7w0Ka',
|
||||
}),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
|
@ -1,13 +1,11 @@
|
|||
import clsx from 'clsx';
|
||||
import type { InterviewsStudyList } from 'contentlayer/generated';
|
||||
import { RiArrowRightLine } from 'react-icons/ri';
|
||||
|
||||
import type { PreparationPlanSchedule } from '~/data/plans/PreparationPlans';
|
||||
|
||||
import InterviewsEntityProgress from '~/components/interviews/common/InterviewsEntityProgress';
|
||||
import type {
|
||||
QuestionList_DEPRECATED,
|
||||
QuestionListTheme_DEPRECATED,
|
||||
} from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import type { QuestionList_DEPRECATED } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import QuestionStudyAllocationLabel from '~/components/interviews/questions/metadata/QuestionStudyAllocationLabel';
|
||||
import { useIntl } from '~/components/intl';
|
||||
import Anchor from '~/components/ui/Anchor';
|
||||
|
|
@ -27,23 +25,29 @@ import { countNumberOfQuestionsInList } from '~/db/QuestionsUtils';
|
|||
|
||||
type Props = Readonly<{
|
||||
completionCount?: number;
|
||||
icon?: (props: React.ComponentProps<'svg'>) => JSX.Element;
|
||||
isStarted?: boolean;
|
||||
metadata: QuestionList_DEPRECATED;
|
||||
metadata: InterviewsStudyList | QuestionList_DEPRECATED;
|
||||
schedule?: PreparationPlanSchedule;
|
||||
theme: QuestionListTheme_DEPRECATED;
|
||||
}>;
|
||||
|
||||
export default function InterviewsStudyListCard({
|
||||
completionCount = 0,
|
||||
metadata,
|
||||
schedule,
|
||||
theme,
|
||||
icon: Icon,
|
||||
isStarted,
|
||||
}: Props) {
|
||||
const intl = useIntl();
|
||||
|
||||
const { name, shortDescription, questions, href } = metadata;
|
||||
const questionCount = countNumberOfQuestionsInList(questions);
|
||||
const { name, shortDescription, href } = metadata;
|
||||
const questionCount =
|
||||
'questions' in metadata
|
||||
? countNumberOfQuestionsInList(metadata.questions)
|
||||
: (metadata.questionsAlgo?.length ?? 0) +
|
||||
(metadata.questionsJavaScript?.length ?? 0) +
|
||||
(metadata.questionsQuiz?.length ?? 0) +
|
||||
(metadata.questionsUserInterface?.length ?? 0);
|
||||
|
||||
return (
|
||||
<div
|
||||
|
|
@ -57,18 +61,18 @@ export default function InterviewsStudyListCard({
|
|||
['border', themeBorderElementColor],
|
||||
)}>
|
||||
<div className="flex flex-1 flex-col gap-6 md:flex-row md:items-center">
|
||||
<div
|
||||
className={clsx(
|
||||
'flex items-center justify-center',
|
||||
'size-12 shrink-0',
|
||||
'rounded-md',
|
||||
themeBackgroundLayerEmphasized,
|
||||
themeGlassyBorder,
|
||||
)}>
|
||||
<theme.iconOutline
|
||||
className={clsx('size-6', themeTextSubtitleColor)}
|
||||
/>
|
||||
</div>
|
||||
{Icon && (
|
||||
<div
|
||||
className={clsx(
|
||||
'flex items-center justify-center',
|
||||
'size-12 shrink-0',
|
||||
'rounded-md',
|
||||
themeBackgroundLayerEmphasized,
|
||||
themeGlassyBorder,
|
||||
)}>
|
||||
<Icon className={clsx('size-6', themeTextSubtitleColor)} />
|
||||
</div>
|
||||
)}
|
||||
<div className="flex flex-1 flex-col gap-4">
|
||||
<div className="flex flex-col items-start gap-1">
|
||||
<div className="flex items-center gap-3">
|
||||
|
|
|
|||
|
|
@ -11,8 +11,6 @@ import url from 'url';
|
|||
import { trpc } from '~/hooks/trpc';
|
||||
import { useAuthSignInUp } from '~/hooks/user/useAuthFns';
|
||||
|
||||
import { INTERVIEWS_REVAMP_2024 } from '~/data/FeatureFlags';
|
||||
|
||||
import ConfirmationDialog from '~/components/common/ConfirmationDialog';
|
||||
import { useToast } from '~/components/global/toasts/useToast';
|
||||
import { useUserProfile } from '~/components/global/UserProfileProvider';
|
||||
|
|
@ -43,14 +41,12 @@ type Props = Readonly<{
|
|||
questionCount: number;
|
||||
questionListKey: string;
|
||||
questions: ReadonlyArray<QuestionMetadata>;
|
||||
themeBackgroundClass: string;
|
||||
}>;
|
||||
|
||||
export default function QuestionsListSession({
|
||||
questionListKey,
|
||||
progressTrackingAvailableToNonPremiumUsers,
|
||||
questionCount,
|
||||
themeBackgroundClass,
|
||||
questions,
|
||||
overallProgress,
|
||||
feature,
|
||||
|
|
@ -283,12 +279,10 @@ export default function QuestionsListSession({
|
|||
id: 'zQFib0',
|
||||
})}
|
||||
progressClass={
|
||||
INTERVIEWS_REVAMP_2024
|
||||
? getProgressBarGradient({
|
||||
total: completedQuestions,
|
||||
value: questionCount,
|
||||
}).className
|
||||
: themeBackgroundClass
|
||||
getProgressBarGradient({
|
||||
total: completedQuestions,
|
||||
value: questionCount,
|
||||
}).className
|
||||
}
|
||||
total={questionCount}
|
||||
value={completedQuestions}
|
||||
|
|
|
|||
|
|
@ -29,13 +29,11 @@ type Props = Readonly<{
|
|||
progressTrackingAvailableToNonPremiumUsers?: boolean;
|
||||
questions: ReadonlyArray<QuestionMetadata>;
|
||||
questionsSessionKey?: string;
|
||||
themeBackgroundClass: string;
|
||||
title: string;
|
||||
}>;
|
||||
|
||||
export default function QuestionsLearningListPageTitleSection({
|
||||
description,
|
||||
themeBackgroundClass,
|
||||
title,
|
||||
features,
|
||||
overallProgress,
|
||||
|
|
@ -93,7 +91,6 @@ export default function QuestionsLearningListPageTitleSection({
|
|||
questionCount={questions.length}
|
||||
questionListKey={props.questionsSessionKey}
|
||||
questions={questions}
|
||||
themeBackgroundClass={themeBackgroundClass}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,119 +0,0 @@
|
|||
import clsx from 'clsx';
|
||||
import type { ReactNode } from 'react';
|
||||
|
||||
import type { PreparationPlanSchedule } from '~/data/plans/PreparationPlans';
|
||||
|
||||
import QuestionCountLabel from '~/components/interviews/questions/metadata/QuestionCountLabel';
|
||||
import QuestionDifficultySummary from '~/components/interviews/questions/metadata/QuestionDifficultySummary';
|
||||
import QuestionStudyAllocationLabel from '~/components/interviews/questions/metadata/QuestionStudyAllocationLabel';
|
||||
import Heading from '~/components/ui/Heading';
|
||||
import Text from '~/components/ui/Text';
|
||||
|
||||
import type { QuestionProgress } from '~/db/QuestionsProgressTypes';
|
||||
|
||||
import QuestionsListSession from './QuestionsListSession';
|
||||
import type {
|
||||
QuestionDifficulty,
|
||||
QuestionFeatureType,
|
||||
QuestionMetadata,
|
||||
} from '../../common/QuestionsTypes';
|
||||
|
||||
type Props = Readonly<{
|
||||
description?: ReactNode;
|
||||
difficultySummary?: Record<QuestionDifficulty, number>;
|
||||
feature?: QuestionFeatureType;
|
||||
icon: (props: React.ComponentProps<'svg'>) => JSX.Element;
|
||||
logoImgSrc?: string;
|
||||
overallProgress: ReadonlyArray<QuestionProgress>;
|
||||
progressTrackingAvailableToNonPremiumUsers?: boolean;
|
||||
questionCount: number;
|
||||
questionListKey: string;
|
||||
questions: ReadonlyArray<QuestionMetadata>;
|
||||
schedule?: PreparationPlanSchedule;
|
||||
themeBackgroundClass: string;
|
||||
title: string;
|
||||
}>;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
export default function QuestionsStudyListTitleSection_DEPRECATED({
|
||||
description,
|
||||
difficultySummary,
|
||||
icon: Icon,
|
||||
logoImgSrc,
|
||||
progressTrackingAvailableToNonPremiumUsers = false,
|
||||
questionListKey,
|
||||
questionCount,
|
||||
schedule,
|
||||
themeBackgroundClass,
|
||||
title,
|
||||
overallProgress,
|
||||
questions,
|
||||
feature = 'premium-questions',
|
||||
}: Props) {
|
||||
return (
|
||||
<div className="flex flex-col justify-between gap-x-8 gap-y-4 md:flex-row">
|
||||
<div className="flex flex-col gap-4">
|
||||
<div className="flex gap-x-6">
|
||||
<div
|
||||
className={clsx(
|
||||
'inline-flex shrink-0 items-center justify-center',
|
||||
'size-16 rounded-lg',
|
||||
'text-white',
|
||||
themeBackgroundClass,
|
||||
)}>
|
||||
{logoImgSrc ? (
|
||||
<img
|
||||
alt={title}
|
||||
className="size-10"
|
||||
decoding="async"
|
||||
loading="lazy"
|
||||
src={logoImgSrc}
|
||||
/>
|
||||
) : (
|
||||
<Icon aria-hidden={true} className="size-10" />
|
||||
)}
|
||||
</div>
|
||||
<div className="flex flex-col gap-y-2">
|
||||
<Heading level="heading5">{title}</Heading>
|
||||
<div className="flex flex-wrap items-center gap-x-8 gap-y-2">
|
||||
<QuestionCountLabel count={questionCount} showIcon={true} />
|
||||
{schedule != null && (
|
||||
<QuestionStudyAllocationLabel
|
||||
frequency={schedule.frequency}
|
||||
hours={schedule.hours}
|
||||
showIcon={true}
|
||||
/>
|
||||
)}
|
||||
{difficultySummary && (
|
||||
<QuestionDifficultySummary
|
||||
easy={difficultySummary.easy}
|
||||
hard={difficultySummary.hard}
|
||||
medium={difficultySummary.medium}
|
||||
showIcon={true}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{description && (
|
||||
<Text className="block max-w-3xl" color="secondary" size="body2">
|
||||
{description}
|
||||
</Text>
|
||||
)}
|
||||
</div>
|
||||
<QuestionsListSession
|
||||
feature={feature}
|
||||
overallProgress={overallProgress}
|
||||
progressTrackingAvailableToNonPremiumUsers={
|
||||
progressTrackingAvailableToNonPremiumUsers
|
||||
}
|
||||
questionCount={questionCount}
|
||||
questionListKey={questionListKey}
|
||||
questions={questions}
|
||||
themeBackgroundClass={themeBackgroundClass}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -18,7 +18,6 @@ import Popover from '~/components/ui/Popover';
|
|||
import Text from '~/components/ui/Text';
|
||||
import {
|
||||
themeBorderElementColor,
|
||||
themeGradientGreenYellow,
|
||||
themeOutlineElementBrandColor_FocusVisible,
|
||||
themeTextBrandColor_GroupHover,
|
||||
themeTextSubtleColor,
|
||||
|
|
@ -208,7 +207,6 @@ type CommonProps = Readonly<{
|
|||
questionsSessionKey?: string;
|
||||
showQuestionCountCard?: boolean;
|
||||
showRecommendedItemsDropdown?: boolean;
|
||||
themeBackgroundClass?: string;
|
||||
title: string;
|
||||
}>;
|
||||
|
||||
|
|
@ -226,7 +224,6 @@ type Props = WithIconProps | WithLogoProps;
|
|||
|
||||
export default function InterviewsRecommendedPrepStrategyPageTitleSection({
|
||||
description,
|
||||
themeBackgroundClass,
|
||||
title,
|
||||
features,
|
||||
longDescription,
|
||||
|
|
@ -284,9 +281,6 @@ export default function InterviewsRecommendedPrepStrategyPageTitleSection({
|
|||
overallProgress={overallProgress ?? []}
|
||||
progressTrackingAvailableToNonPremiumUsers={true}
|
||||
questions={questions ?? []}
|
||||
themeBackgroundClass={
|
||||
themeBackgroundClass ?? themeGradientGreenYellow.className
|
||||
}
|
||||
title={title}
|
||||
{...props}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
import clsx from 'clsx';
|
||||
import type { InterviewsStudyList } from 'contentlayer/generated';
|
||||
|
||||
import {
|
||||
getQuestionListThemes,
|
||||
useQuestionLists_DEPRECATED,
|
||||
} from '~/data/question-lists/QuestionListsHooks';
|
||||
import { usePreparationPlans } from '~/data/plans/PreparationPlansHooks';
|
||||
|
||||
import getProgressBarGradient from '~/components/interviews/common/utils';
|
||||
import { mapFocusAreasBySlug } from '~/components/interviews/questions/content/study-list/FocusAreas';
|
||||
import { FormattedMessage, useIntl } from '~/components/intl';
|
||||
import Button from '~/components/ui/Button';
|
||||
import GradientProgressBar from '~/components/ui/GradientProgressBar/GradientProgressBar';
|
||||
|
|
@ -19,13 +18,12 @@ import {
|
|||
} from '~/components/ui/theme';
|
||||
import Tooltip from '~/components/ui/Tooltip';
|
||||
|
||||
import { countNumberOfQuestionsInList } from '~/db/QuestionsUtils';
|
||||
|
||||
import QuestionCountLabel from '../questions/metadata/QuestionCountLabel';
|
||||
|
||||
import type { LearningSession } from '@prisma/client';
|
||||
|
||||
type Props = Readonly<{
|
||||
focusAreas: ReadonlyArray<InterviewsStudyList>;
|
||||
questionListSessions: Array<
|
||||
LearningSession & { _count: { progress: number } }
|
||||
>;
|
||||
|
|
@ -33,24 +31,43 @@ type Props = Readonly<{
|
|||
|
||||
export default function InterviewsDashboardContinueLearningSection({
|
||||
questionListSessions,
|
||||
focusAreas,
|
||||
}: Props) {
|
||||
const intl = useIntl();
|
||||
const questionLists = useQuestionLists_DEPRECATED();
|
||||
const themes = getQuestionListThemes();
|
||||
// TODO(interviews): need to update once preparation plan is migrated to contentlayer
|
||||
const plans = usePreparationPlans() as unknown as Record<
|
||||
string,
|
||||
InterviewsStudyList
|
||||
>;
|
||||
|
||||
const mapFocusAreas = mapFocusAreasBySlug(focusAreas);
|
||||
const questionLists = { ...plans, ...mapFocusAreas };
|
||||
|
||||
const items = questionListSessions
|
||||
// TODO(interviews): filter out company lists for now because company list
|
||||
// rendering is not yet supported on the dashboard.
|
||||
.filter(({ key }) => questionLists[key] != null)
|
||||
.map(({ key, _count }) => ({
|
||||
completedCount: _count.progress,
|
||||
gradient: themes[key].gradient,
|
||||
href: questionLists[key]?.href,
|
||||
questionsCount: countNumberOfQuestionsInList(
|
||||
questionLists[key].questions,
|
||||
),
|
||||
title: questionLists[key].longName,
|
||||
}));
|
||||
.map(({ key, _count }) => {
|
||||
const {
|
||||
href,
|
||||
longName,
|
||||
questionsAlgo,
|
||||
questionsJavaScript,
|
||||
questionsQuiz,
|
||||
questionsSystemDesign,
|
||||
} = questionLists[key];
|
||||
|
||||
return {
|
||||
completedCount: _count.progress,
|
||||
href,
|
||||
questionsCount:
|
||||
(questionsAlgo?.length ?? 0) +
|
||||
(questionsJavaScript?.length ?? 0) +
|
||||
(questionsQuiz?.length ?? 0) +
|
||||
(questionsSystemDesign?.length ?? 0),
|
||||
title: longName,
|
||||
};
|
||||
});
|
||||
|
||||
return (
|
||||
<Section>
|
||||
|
|
@ -65,7 +82,8 @@ export default function InterviewsDashboardContinueLearningSection({
|
|||
|
||||
<div className={clsx('grid gap-4 lg:grid-cols-2')}>
|
||||
{items.map(({ completedCount, href, title, questionsCount }) => {
|
||||
const progressPercentage = (completedCount / questionsCount) * 100;
|
||||
const progressPercentage =
|
||||
Math.min(completedCount / Math.max(questionsCount, 1), 1) * 100;
|
||||
|
||||
return (
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import type { LearningSession } from '@prisma/client';
|
|||
|
||||
type Props = Readonly<{
|
||||
companyGuides: Array<InterviewsStudyList>;
|
||||
focusAreas: ReadonlyArray<InterviewsStudyList>;
|
||||
guidesProgress: ReadonlyArray<
|
||||
Readonly<{ id: string; slug: string; type: GuideCategory }>
|
||||
>;
|
||||
|
|
@ -58,6 +59,7 @@ export default function InterviewsDashboardMoreLearningSection({
|
|||
questions,
|
||||
questionsProgress,
|
||||
guidesProgress,
|
||||
focusAreas,
|
||||
}: Props) {
|
||||
return (
|
||||
<Section>
|
||||
|
|
@ -96,6 +98,7 @@ export default function InterviewsDashboardMoreLearningSection({
|
|||
/>
|
||||
|
||||
<InterviewsDashboardPracticeByFocusAreasSection
|
||||
focusAreas={focusAreas}
|
||||
questionListSessions={questionListSessions}
|
||||
/>
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ import { useUser } from '@supabase/auth-helpers-react';
|
|||
type Props = Readonly<{
|
||||
bottomContent?: InterviewsListingBottomContent;
|
||||
companyGuides: Array<InterviewsStudyList>;
|
||||
focusAreas: ReadonlyArray<InterviewsStudyList>;
|
||||
preparationPlans: PreparationPlans;
|
||||
questions: {
|
||||
codingQuestions: ReadonlyArray<QuestionMetadata>;
|
||||
|
|
@ -55,6 +56,7 @@ export default function InterviewsDashboardPage({
|
|||
preparationPlans,
|
||||
questions,
|
||||
bottomContent,
|
||||
focusAreas,
|
||||
}: Props) {
|
||||
const user = useUser();
|
||||
const isLoggedIn = !!user;
|
||||
|
|
@ -104,12 +106,14 @@ export default function InterviewsDashboardPage({
|
|||
)}
|
||||
{showContinueLearning && (
|
||||
<InterviewsDashboardContinueLearningSection
|
||||
focusAreas={focusAreas}
|
||||
questionListSessions={sessions}
|
||||
/>
|
||||
)}
|
||||
<InterviewsDashboardRecommendedPreparationStrategy />
|
||||
<InterviewsDashboardMoreLearningSection
|
||||
companyGuides={companyGuides}
|
||||
focusAreas={focusAreas}
|
||||
guidesProgress={guidesProgress ?? []}
|
||||
preparationPlans={preparationPlans}
|
||||
questionListSessions={sessions}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,4 @@
|
|||
import {
|
||||
getPreparationPlanTheme,
|
||||
type PreparationPlans,
|
||||
} from '~/data/plans/PreparationPlans';
|
||||
import { type PreparationPlans } from '~/data/plans/PreparationPlans';
|
||||
|
||||
import InterviewsStudyListCard from '~/components/interviews/questions/listings/learning/InterviewsStudyListCard';
|
||||
import { useIntl } from '~/components/intl';
|
||||
|
|
@ -45,7 +42,6 @@ export default function InterviewsDashboardStudyPlansSection({
|
|||
(session_) => session_.key === studyPlan.type,
|
||||
);
|
||||
const completionCount = session?._count.progress;
|
||||
const theme = getPreparationPlanTheme(studyPlan.type);
|
||||
|
||||
return (
|
||||
<InterviewsStudyListCard
|
||||
|
|
@ -54,7 +50,7 @@ export default function InterviewsDashboardStudyPlansSection({
|
|||
isStarted={session != null}
|
||||
metadata={studyPlan}
|
||||
schedule={studyPlan.schedule}
|
||||
theme={theme}
|
||||
// TODO(interviews): need to pass icon
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
import {
|
||||
categorizeFocusAreas_DEPRECATED,
|
||||
getFocusAreaTheme_DEPRECATED,
|
||||
} from '~/data/focus-areas/FocusAreas';
|
||||
import type { InterviewsStudyList } from 'contentlayer/generated';
|
||||
|
||||
import {
|
||||
categorizeFocusAreas,
|
||||
FocusAreaIcons,
|
||||
} from '~/components/interviews/questions/content/study-list/FocusAreas';
|
||||
import InterviewsStudyListCard from '~/components/interviews/questions/listings/learning/InterviewsStudyListCard';
|
||||
import InterviewsDashboardLearningSection from '~/components/interviews/revamp-dashboard/InterviewsDashboardLearningSection';
|
||||
import { useIntl } from '~/components/intl';
|
||||
|
|
@ -11,6 +12,7 @@ import Text from '~/components/ui/Text';
|
|||
import type { LearningSession } from '@prisma/client';
|
||||
|
||||
type Props = Readonly<{
|
||||
focusAreas: ReadonlyArray<InterviewsStudyList>;
|
||||
questionListSessions: Array<
|
||||
LearningSession & { _count: { progress: number } }
|
||||
>;
|
||||
|
|
@ -18,9 +20,10 @@ type Props = Readonly<{
|
|||
|
||||
export default function InterviewsDashboardPracticeByFocusAreasSection({
|
||||
questionListSessions,
|
||||
focusAreas,
|
||||
}: Props) {
|
||||
const intl = useIntl();
|
||||
const focusAreasCategories = categorizeFocusAreas_DEPRECATED(intl);
|
||||
const focusAreasCategories = categorizeFocusAreas(intl, focusAreas);
|
||||
|
||||
return (
|
||||
<InterviewsDashboardLearningSection
|
||||
|
|
@ -45,18 +48,17 @@ export default function InterviewsDashboardPracticeByFocusAreasSection({
|
|||
<div className="flex flex-col gap-4">
|
||||
{items.map((focusArea) => {
|
||||
const session = questionListSessions.find(
|
||||
(session_) => session_.key === focusArea.type,
|
||||
(session_) => session_.key === focusArea.slug,
|
||||
);
|
||||
const completionCount = session?._count.progress;
|
||||
const theme = getFocusAreaTheme_DEPRECATED(focusArea.type);
|
||||
|
||||
return (
|
||||
<InterviewsStudyListCard
|
||||
key={focusArea.type}
|
||||
key={focusArea.slug}
|
||||
completionCount={completionCount}
|
||||
icon={FocusAreaIcons[focusArea.slug]}
|
||||
isStarted={session != null}
|
||||
metadata={focusArea}
|
||||
theme={theme}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
|
|
|||
|
|
@ -1,215 +0,0 @@
|
|||
import type { IntlShape } from 'react-intl';
|
||||
|
||||
import type {
|
||||
QuestionList_DEPRECATED,
|
||||
QuestionListTheme_DEPRECATED,
|
||||
} from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
|
||||
import {
|
||||
getFocusAreaAccessibility,
|
||||
getFocusAreaThemeAccessibility,
|
||||
} from './items/FocusAreaAccessibility';
|
||||
import {
|
||||
getFocusAreaAsyncOperations,
|
||||
getFocusAreaThemeAsyncOperations,
|
||||
} from './items/FocusAreaAsyncOperations';
|
||||
import {
|
||||
getFocusAreaDataStructuresAlgorithms,
|
||||
getFocusAreaThemeDataStructuresAlgorithms,
|
||||
} from './items/FocusAreaDataStructuresAlgorithms';
|
||||
import {
|
||||
getFocusAreaDesignSystemComponents,
|
||||
getFocusAreaThemeDesignSystemComponents,
|
||||
} from './items/FocusAreaDesignSystemComponents';
|
||||
import {
|
||||
getFocusAreaDOMManipulation,
|
||||
getFocusAreaThemeDOMManipulation,
|
||||
} from './items/FocusAreaDOMManipulation';
|
||||
import {
|
||||
getFocusAreaForms,
|
||||
getFocusAreaThemeForms,
|
||||
} from './items/FocusAreaForms';
|
||||
import {
|
||||
getFocusAreaJavaScriptPolyfills,
|
||||
getFocusAreaThemeJavaScriptPolyfills,
|
||||
} from './items/FocusAreaJavaScriptPolyfills';
|
||||
import {
|
||||
getFocusAreaLodash,
|
||||
getFocusAreaThemeLodash,
|
||||
} from './items/FocusAreaLodash';
|
||||
import {
|
||||
getFocusAreaStateManagement,
|
||||
getFocusAreaThemeStateManagement,
|
||||
} from './items/FocusAreaStateManagement';
|
||||
|
||||
/** @deprecated */
|
||||
export type FocusAreaType_DEPRECATED =
|
||||
| 'accessibility'
|
||||
| 'async-operations'
|
||||
| 'data-structures-algorithms'
|
||||
| 'design-system-components'
|
||||
| 'dom-manipulation'
|
||||
| 'forms'
|
||||
| 'javascript-polyfills'
|
||||
| 'lodash'
|
||||
| 'state-management';
|
||||
|
||||
/** @deprecated Can only contain serializable values as it's passed between the server-client boundary. */
|
||||
export type FocusArea_DEPRECATED = QuestionList_DEPRECATED &
|
||||
Readonly<{
|
||||
type: FocusAreaType_DEPRECATED;
|
||||
}>;
|
||||
|
||||
/** @deprecated */
|
||||
export type FocusAreas_DEPRECATED = Record<
|
||||
FocusAreaType_DEPRECATED,
|
||||
FocusArea_DEPRECATED
|
||||
>;
|
||||
|
||||
/** @deprecated */
|
||||
export function getFocusAreas_DEPRECATED(
|
||||
intl: IntlShape,
|
||||
): FocusAreas_DEPRECATED {
|
||||
const focusAreas: FocusAreas_DEPRECATED = {
|
||||
accessibility: getFocusArea_DEPRECATED('accessibility', intl),
|
||||
'async-operations': getFocusArea_DEPRECATED('async-operations', intl),
|
||||
'data-structures-algorithms': getFocusArea_DEPRECATED(
|
||||
'data-structures-algorithms',
|
||||
intl,
|
||||
),
|
||||
'design-system-components': getFocusArea_DEPRECATED(
|
||||
'design-system-components',
|
||||
intl,
|
||||
),
|
||||
'dom-manipulation': getFocusArea_DEPRECATED('dom-manipulation', intl),
|
||||
forms: getFocusArea_DEPRECATED('forms', intl),
|
||||
'javascript-polyfills': getFocusArea_DEPRECATED(
|
||||
'javascript-polyfills',
|
||||
intl,
|
||||
),
|
||||
lodash: getFocusArea_DEPRECATED('lodash', intl),
|
||||
'state-management': getFocusArea_DEPRECATED('state-management', intl),
|
||||
};
|
||||
|
||||
return focusAreas;
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
export function getFocusArea_DEPRECATED(
|
||||
focusArea: FocusAreaType_DEPRECATED,
|
||||
intl: IntlShape,
|
||||
): FocusArea_DEPRECATED {
|
||||
switch (focusArea) {
|
||||
case 'accessibility':
|
||||
return getFocusAreaAccessibility(intl);
|
||||
case 'data-structures-algorithms':
|
||||
return getFocusAreaDataStructuresAlgorithms(intl);
|
||||
case 'forms':
|
||||
return getFocusAreaForms(intl);
|
||||
case 'lodash':
|
||||
return getFocusAreaLodash(intl);
|
||||
case 'async-operations':
|
||||
return getFocusAreaAsyncOperations(intl);
|
||||
case 'design-system-components':
|
||||
return getFocusAreaDesignSystemComponents(intl);
|
||||
case 'dom-manipulation':
|
||||
return getFocusAreaDOMManipulation(intl);
|
||||
case 'javascript-polyfills':
|
||||
return getFocusAreaJavaScriptPolyfills(intl);
|
||||
case 'state-management':
|
||||
return getFocusAreaStateManagement(intl);
|
||||
}
|
||||
}
|
||||
|
||||
export function getFocusAreaThemes_DEPRECATED(): Record<
|
||||
FocusAreaType_DEPRECATED,
|
||||
QuestionListTheme_DEPRECATED
|
||||
> {
|
||||
return {
|
||||
accessibility: getFocusAreaTheme_DEPRECATED('accessibility'),
|
||||
'async-operations': getFocusAreaTheme_DEPRECATED('async-operations'),
|
||||
'data-structures-algorithms': getFocusAreaTheme_DEPRECATED(
|
||||
'data-structures-algorithms',
|
||||
),
|
||||
'design-system-components': getFocusAreaTheme_DEPRECATED(
|
||||
'design-system-components',
|
||||
),
|
||||
'dom-manipulation': getFocusAreaTheme_DEPRECATED('dom-manipulation'),
|
||||
forms: getFocusAreaTheme_DEPRECATED('forms'),
|
||||
'javascript-polyfills': getFocusAreaTheme_DEPRECATED(
|
||||
'javascript-polyfills',
|
||||
),
|
||||
lodash: getFocusAreaTheme_DEPRECATED('lodash'),
|
||||
'state-management': getFocusAreaTheme_DEPRECATED('state-management'),
|
||||
};
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
export function getFocusAreaTheme_DEPRECATED(
|
||||
focusArea: string,
|
||||
): QuestionListTheme_DEPRECATED {
|
||||
switch (focusArea) {
|
||||
case 'accessibility':
|
||||
return getFocusAreaThemeAccessibility();
|
||||
case 'data-structures-algorithms':
|
||||
return getFocusAreaThemeDataStructuresAlgorithms();
|
||||
case 'forms':
|
||||
return getFocusAreaThemeForms();
|
||||
case 'lodash':
|
||||
return getFocusAreaThemeLodash();
|
||||
case 'async-operations':
|
||||
return getFocusAreaThemeAsyncOperations();
|
||||
case 'design-system-components':
|
||||
return getFocusAreaThemeDesignSystemComponents();
|
||||
case 'dom-manipulation':
|
||||
return getFocusAreaThemeDOMManipulation();
|
||||
case 'javascript-polyfills':
|
||||
return getFocusAreaThemeJavaScriptPolyfills();
|
||||
case 'state-management':
|
||||
return getFocusAreaThemeStateManagement();
|
||||
default:
|
||||
throw Error('No such focus area');
|
||||
}
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
export function categorizeFocusAreas_DEPRECATED(intl: IntlShape) {
|
||||
const focusAreas = getFocusAreas_DEPRECATED(intl);
|
||||
|
||||
return [
|
||||
{
|
||||
items: [
|
||||
focusAreas['javascript-polyfills'],
|
||||
focusAreas['async-operations'],
|
||||
focusAreas.lodash,
|
||||
],
|
||||
title: intl.formatMessage({
|
||||
defaultMessage: 'JavaScript Engineering',
|
||||
description: 'Title for focus area type',
|
||||
id: 'er249T',
|
||||
}),
|
||||
},
|
||||
{
|
||||
items: [
|
||||
focusAreas['dom-manipulation'],
|
||||
focusAreas.forms,
|
||||
focusAreas['design-system-components'],
|
||||
focusAreas.accessibility,
|
||||
focusAreas['state-management'],
|
||||
],
|
||||
title: intl.formatMessage({
|
||||
defaultMessage: 'User Interface Development',
|
||||
description: 'Title for focus area type',
|
||||
id: '2M6LN4',
|
||||
}),
|
||||
},
|
||||
{
|
||||
items: [focusAreas['data-structures-algorithms']],
|
||||
title: intl.formatMessage({
|
||||
defaultMessage: 'Computer Science Foundations',
|
||||
description: 'Title for focus area type',
|
||||
id: 'L7w0Ka',
|
||||
}),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
import { useIntl } from '~/components/intl';
|
||||
|
||||
import { getFocusAreas_DEPRECATED } from './FocusAreas';
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
export function useFocusAreas_DEPRECATED() {
|
||||
const intl = useIntl();
|
||||
|
||||
return getFocusAreas_DEPRECATED(intl);
|
||||
}
|
||||
|
|
@ -1,90 +0,0 @@
|
|||
import { BiUniversalAccess } from 'react-icons/bi';
|
||||
import type { IntlShape } from 'react-intl';
|
||||
|
||||
import type { QuestionListTheme_DEPRECATED } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import type { ThemeGradient } from '~/components/ui/theme';
|
||||
|
||||
import type { FocusArea_DEPRECATED } from '../FocusAreas';
|
||||
|
||||
export function getFocusAreaAccessibility(
|
||||
intl: IntlShape,
|
||||
): FocusArea_DEPRECATED {
|
||||
return {
|
||||
description: intl.formatMessage({
|
||||
defaultMessage: 'Targeted practice on Accessibility interview questions',
|
||||
description: 'Description for interview preparation focus area',
|
||||
id: 'XauDQh',
|
||||
}),
|
||||
href: '/focus-areas/accessibility',
|
||||
longName: intl.formatMessage({
|
||||
defaultMessage: 'Accessibility',
|
||||
description: 'Name of focus area questions',
|
||||
id: '1kiNiW',
|
||||
}),
|
||||
name: intl.formatMessage({
|
||||
defaultMessage: 'Accessibility',
|
||||
description: 'Name of focus area questions',
|
||||
id: '1kiNiW',
|
||||
}),
|
||||
questions: {
|
||||
algo: [],
|
||||
javascript: [],
|
||||
quiz: [],
|
||||
'system-design': [],
|
||||
'user-interface': [
|
||||
'accordion',
|
||||
'accordion-ii',
|
||||
'accordion-iii',
|
||||
'auth-code-input',
|
||||
'file-explorer-ii',
|
||||
'modal-dialog',
|
||||
'modal-dialog-ii',
|
||||
'modal-dialog-iii',
|
||||
'modal-dialog-iv',
|
||||
'tabs',
|
||||
'tabs-ii',
|
||||
'tabs-iii',
|
||||
],
|
||||
},
|
||||
seo: {
|
||||
description: intl.formatMessage({
|
||||
defaultMessage:
|
||||
'Practice front end Accessibility interview questions on semantic HTML, ARIA, and screen readers. Code in-browser with curated solutions from ex-interviewers.',
|
||||
description: 'Description for interview preparation focus area',
|
||||
id: 'FwKG3p',
|
||||
}),
|
||||
socialTitle: intl.formatMessage({
|
||||
defaultMessage: 'Accessibility Interview Questions | GreatFrontEnd',
|
||||
description: 'Social title for interview preparation focus area',
|
||||
id: 'ZcKmXM',
|
||||
}),
|
||||
title: intl.formatMessage({
|
||||
defaultMessage:
|
||||
'Practice Accessibility Interview Questions with Solutions',
|
||||
description: 'Title for interview preparation focus area',
|
||||
id: 'GQfy69',
|
||||
}),
|
||||
},
|
||||
shortDescription: intl.formatMessage({
|
||||
defaultMessage:
|
||||
'Practice developing inclusive and accessible web experiences.',
|
||||
description: 'Description for interview preparation focus area',
|
||||
id: 'Sj1CaY',
|
||||
}),
|
||||
type: 'accessibility',
|
||||
};
|
||||
}
|
||||
|
||||
const gradient: ThemeGradient<'#f953c6', '#b91d73'> = {
|
||||
className: 'bg-[linear-gradient(133.77deg,_#f953c6_0%,_#b91d73_97.95%)]',
|
||||
endColor: '#b91d73',
|
||||
startColor: '#f953c6',
|
||||
};
|
||||
|
||||
export function getFocusAreaThemeAccessibility(): QuestionListTheme_DEPRECATED {
|
||||
return {
|
||||
gradient,
|
||||
iconOutline: BiUniversalAccess,
|
||||
iconSolid: BiUniversalAccess,
|
||||
};
|
||||
}
|
||||
|
|
@ -1,113 +0,0 @@
|
|||
import { RiRefreshLine } from 'react-icons/ri';
|
||||
import type { IntlShape } from 'react-intl';
|
||||
|
||||
import type { QuestionListTheme_DEPRECATED } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import type { ThemeGradient } from '~/components/ui/theme';
|
||||
|
||||
import type { FocusArea_DEPRECATED } from '../FocusAreas';
|
||||
|
||||
export function getFocusAreaAsyncOperations(
|
||||
intl: IntlShape,
|
||||
): FocusArea_DEPRECATED {
|
||||
return {
|
||||
description: intl.formatMessage({
|
||||
defaultMessage:
|
||||
'Targeted practice on Async Operations interview questions',
|
||||
description: 'Description for interview preparation focus area',
|
||||
id: 'Xs7UBt',
|
||||
}),
|
||||
href: '/focus-areas/async-operations',
|
||||
longName: intl.formatMessage({
|
||||
defaultMessage: 'Async Operations',
|
||||
description: 'Name of focus area questions',
|
||||
id: 'LGm3GF',
|
||||
}),
|
||||
name: intl.formatMessage({
|
||||
defaultMessage: 'Async Operations',
|
||||
description: 'Name of focus area questions',
|
||||
id: 'LGm3GF',
|
||||
}),
|
||||
questions: {
|
||||
algo: [],
|
||||
javascript: [
|
||||
'cancellable-interval',
|
||||
'cancellable-timeout',
|
||||
'debounce',
|
||||
'debounce-ii',
|
||||
'map-async',
|
||||
'map-async-limit',
|
||||
'promise-all',
|
||||
'promise-all-settled',
|
||||
'promise-any',
|
||||
'promise-merge',
|
||||
'promise-race',
|
||||
'promise-reject',
|
||||
'promise-resolve',
|
||||
'promise-timeout',
|
||||
'promise-with-resolvers',
|
||||
'promisify',
|
||||
'promisify-ii',
|
||||
'resumable-interval',
|
||||
'sleep',
|
||||
'throttle',
|
||||
],
|
||||
quiz: [],
|
||||
'system-design': [],
|
||||
'user-interface': [
|
||||
'analog-clock',
|
||||
'birth-year-histogram',
|
||||
'digital-clock',
|
||||
'grid-lights',
|
||||
'progress-bars',
|
||||
'progress-bars-ii',
|
||||
'progress-bars-iii',
|
||||
'progress-bars-iv',
|
||||
'job-board',
|
||||
'like-button',
|
||||
'stopwatch',
|
||||
'traffic-light',
|
||||
'whack-a-mole',
|
||||
],
|
||||
},
|
||||
seo: {
|
||||
description: intl.formatMessage({
|
||||
defaultMessage:
|
||||
'Practice async operations interview questions on async / await, Promises, and callbacks. Code in-browser with quality solutions and tests from ex-interviewers.',
|
||||
description: 'Description for interview preparation focus area',
|
||||
id: 'vccqVg',
|
||||
}),
|
||||
socialTitle: intl.formatMessage({
|
||||
defaultMessage: 'Async Operations Interview Questions | GreatFrontEnd',
|
||||
description: 'Social title for interview preparation focus area',
|
||||
id: 'Adsxn4',
|
||||
}),
|
||||
title: intl.formatMessage({
|
||||
defaultMessage:
|
||||
'Practice Async Operations Interview Questions with Solutions',
|
||||
description: 'Title for interview preparation focus area',
|
||||
id: 'nQoQzP',
|
||||
}),
|
||||
},
|
||||
shortDescription: intl.formatMessage({
|
||||
defaultMessage:
|
||||
'Sharpen your skills in asynchronous programming by practicing the use of async/await, Promises, and callback functions.',
|
||||
description: 'Description for interview preparation focus area',
|
||||
id: 'UrnJdy',
|
||||
}),
|
||||
type: 'async-operations',
|
||||
};
|
||||
}
|
||||
|
||||
const gradient: ThemeGradient<'#8E2DE2', '#4A00E0'> = {
|
||||
className: 'bg-[linear-gradient(133.77deg,_#8E2DE2_0%,_#4A00E0_97.95%)]',
|
||||
endColor: '#4A00E0',
|
||||
startColor: '#8E2DE2',
|
||||
};
|
||||
|
||||
export function getFocusAreaThemeAsyncOperations(): QuestionListTheme_DEPRECATED {
|
||||
return {
|
||||
gradient,
|
||||
iconOutline: RiRefreshLine,
|
||||
iconSolid: RiRefreshLine,
|
||||
};
|
||||
}
|
||||
|
|
@ -1,89 +0,0 @@
|
|||
import { RiWindowFill } from 'react-icons/ri';
|
||||
import type { IntlShape } from 'react-intl';
|
||||
|
||||
import type { QuestionListTheme_DEPRECATED } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import type { ThemeGradient } from '~/components/ui/theme';
|
||||
|
||||
import type { FocusArea_DEPRECATED } from '../FocusAreas';
|
||||
|
||||
export function getFocusAreaDOMManipulation(
|
||||
intl: IntlShape,
|
||||
): FocusArea_DEPRECATED {
|
||||
return {
|
||||
description: intl.formatMessage({
|
||||
defaultMessage:
|
||||
'Targeted practice on DOM Manipulation interview questions',
|
||||
description: 'Description for interview preparation focus area',
|
||||
id: '8Luumm',
|
||||
}),
|
||||
href: '/focus-areas/dom-manipulation',
|
||||
longName: intl.formatMessage({
|
||||
defaultMessage: 'DOM Manipulation',
|
||||
description: 'Name of focus area questions',
|
||||
id: 'RvPm3x',
|
||||
}),
|
||||
name: intl.formatMessage({
|
||||
defaultMessage: 'DOM Manipulation',
|
||||
description: 'Name of focus area questions',
|
||||
id: 'RvPm3x',
|
||||
}),
|
||||
questions: {
|
||||
algo: [],
|
||||
javascript: [
|
||||
'get-elements-by-class-name',
|
||||
'get-elements-by-style',
|
||||
'get-elements-by-tag-name',
|
||||
'get-elements-by-tag-name-hierarchy',
|
||||
'jquery-class-manipulation',
|
||||
'jquery-css',
|
||||
'html-serializer',
|
||||
'identical-dom-trees',
|
||||
'table-of-contents',
|
||||
'text-search',
|
||||
],
|
||||
quiz: [],
|
||||
'system-design': [],
|
||||
'user-interface': [],
|
||||
},
|
||||
seo: {
|
||||
description: intl.formatMessage({
|
||||
defaultMessage:
|
||||
'Practice DOM manipulation interview questions on CSS selectors, DOM traversal, and element manipulation. Code in-browser with solutions from ex-interviewers.',
|
||||
description: 'Description for interview preparation focus area',
|
||||
id: 'kWg+JN',
|
||||
}),
|
||||
socialTitle: intl.formatMessage({
|
||||
defaultMessage: 'DOM Manipulation Interview Questions | GreatFrontEnd',
|
||||
description: 'Social title for interview preparation focus area',
|
||||
id: 'l1pp5/',
|
||||
}),
|
||||
title: intl.formatMessage({
|
||||
defaultMessage:
|
||||
'Practice DOM Manipulation Interview Questions with Solutions',
|
||||
description: 'Title for interview preparation focus area',
|
||||
id: 'o4CKFi',
|
||||
}),
|
||||
},
|
||||
shortDescription: intl.formatMessage({
|
||||
defaultMessage:
|
||||
'Familiarize with selecting elements using CSS selectors, traverse the DOM hierarchy, and manipulate their properties, content, and styles.',
|
||||
description: 'Description for interview preparation focus area',
|
||||
id: 'yAJsl0',
|
||||
}),
|
||||
type: 'dom-manipulation',
|
||||
};
|
||||
}
|
||||
|
||||
const gradient: ThemeGradient<'#bc4e9c', '#f80759'> = {
|
||||
className: 'bg-[linear-gradient(133.77deg,_#bc4e9c_0%,_#f80759_97.95%)]',
|
||||
endColor: '#f80759',
|
||||
startColor: '#bc4e9c',
|
||||
};
|
||||
|
||||
export function getFocusAreaThemeDOMManipulation(): QuestionListTheme_DEPRECATED {
|
||||
return {
|
||||
gradient,
|
||||
iconOutline: RiWindowFill,
|
||||
iconSolid: RiWindowFill,
|
||||
};
|
||||
}
|
||||
|
|
@ -1,110 +0,0 @@
|
|||
import { TbBinaryTree } from 'react-icons/tb';
|
||||
import type { IntlShape } from 'react-intl';
|
||||
|
||||
import type { QuestionListTheme_DEPRECATED } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import { QuestionCount } from '~/components/interviews/questions/listings/stats/QuestionCount';
|
||||
import type { ThemeGradient } from '~/components/ui/theme';
|
||||
|
||||
import type { FocusArea_DEPRECATED } from '../FocusAreas';
|
||||
|
||||
export function getFocusAreaDataStructuresAlgorithms(
|
||||
intl: IntlShape,
|
||||
): FocusArea_DEPRECATED {
|
||||
return {
|
||||
description: intl.formatMessage(
|
||||
{
|
||||
defaultMessage:
|
||||
'Targeted practice on Data Structures & Algorithms interview questions',
|
||||
description: 'Description for interview preparation focus area',
|
||||
id: 'lf+GYY',
|
||||
},
|
||||
{
|
||||
numberOfQuestions: QuestionCount,
|
||||
},
|
||||
),
|
||||
href: '/focus-areas/data-structures-algorithms',
|
||||
longName: intl.formatMessage({
|
||||
defaultMessage: 'Data Structures & Algorithms',
|
||||
description: 'Name of focus area questions',
|
||||
id: 'qZRTqi',
|
||||
}),
|
||||
name: intl.formatMessage({
|
||||
defaultMessage: 'Data Structures & Algorithms',
|
||||
description: 'Name of focus area questions',
|
||||
id: 'qZRTqi',
|
||||
}),
|
||||
questions: {
|
||||
algo: [
|
||||
'stack',
|
||||
'queue',
|
||||
'merge-sort',
|
||||
'quick-sort',
|
||||
'heap-sort',
|
||||
'topological-sort',
|
||||
'insertion-sort',
|
||||
'selection-sort',
|
||||
'binary-search',
|
||||
'depth-first-search',
|
||||
'breadth-first-search',
|
||||
],
|
||||
javascript: [
|
||||
'data-merging',
|
||||
'data-selection',
|
||||
'event-emitter',
|
||||
'event-emitter-ii',
|
||||
'backbone-model',
|
||||
'table-of-contents',
|
||||
'unique-array',
|
||||
],
|
||||
quiz: [],
|
||||
'system-design': [],
|
||||
'user-interface': [
|
||||
'transfer-list',
|
||||
'transfer-list-ii',
|
||||
'undoable-counter',
|
||||
'wordle',
|
||||
],
|
||||
},
|
||||
seo: {
|
||||
description: intl.formatMessage({
|
||||
defaultMessage:
|
||||
'Practice data structures and algorithms interview questions in-browser with JavaScript / TypeScript solutions from ex-interviewers',
|
||||
description: 'Description for interview preparation focus area',
|
||||
id: 'urxhTe',
|
||||
}),
|
||||
socialTitle: intl.formatMessage({
|
||||
defaultMessage:
|
||||
'Data Structures and Algorithms Interview Questions | GreatFrontEnd',
|
||||
description: 'Social title for interview preparation focus area',
|
||||
id: 'fDWt7h',
|
||||
}),
|
||||
title: intl.formatMessage({
|
||||
defaultMessage:
|
||||
'Practice Data Structures and Algorithms Interview Questions',
|
||||
description: 'Title for interview preparation focus area',
|
||||
id: 'EteZq/',
|
||||
}),
|
||||
},
|
||||
shortDescription: intl.formatMessage({
|
||||
defaultMessage:
|
||||
'Hone your computer science fundamentals by implementing important data structures and algorithms from scratch.',
|
||||
description: 'Description for interview preparation focus area',
|
||||
id: 'HMJJLh',
|
||||
}),
|
||||
type: 'data-structures-algorithms',
|
||||
};
|
||||
}
|
||||
|
||||
const gradient: ThemeGradient<'#50C9C3', '#96DEDA'> = {
|
||||
className: 'bg-[linear-gradient(133.77deg,_#50C9C3_0%,_#96DEDA_97.95%)]',
|
||||
endColor: '#96DEDA',
|
||||
startColor: '#50C9C3',
|
||||
};
|
||||
|
||||
export function getFocusAreaThemeDataStructuresAlgorithms(): QuestionListTheme_DEPRECATED {
|
||||
return {
|
||||
gradient,
|
||||
iconOutline: TbBinaryTree,
|
||||
iconSolid: TbBinaryTree,
|
||||
};
|
||||
}
|
||||
|
|
@ -1,91 +0,0 @@
|
|||
import { RiDashboardLine } from 'react-icons/ri';
|
||||
import type { IntlShape } from 'react-intl';
|
||||
|
||||
import type { QuestionListTheme_DEPRECATED } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import type { ThemeGradient } from '~/components/ui/theme';
|
||||
|
||||
import type { FocusArea_DEPRECATED } from '../FocusAreas';
|
||||
|
||||
export function getFocusAreaDesignSystemComponents(
|
||||
intl: IntlShape,
|
||||
): FocusArea_DEPRECATED {
|
||||
return {
|
||||
description: intl.formatMessage({
|
||||
defaultMessage:
|
||||
'Targeted practice on Design System Components interview questions',
|
||||
description: 'Description for interview preparation focus area',
|
||||
id: 't55S7k',
|
||||
}),
|
||||
href: '/focus-areas/design-system-components',
|
||||
longName: intl.formatMessage({
|
||||
defaultMessage: 'Design System Components',
|
||||
description: 'Name of focus area questions',
|
||||
id: 'onNjnt',
|
||||
}),
|
||||
name: intl.formatMessage({
|
||||
defaultMessage: 'Design System Components',
|
||||
description: 'Name of focus area questions',
|
||||
id: 'onNjnt',
|
||||
}),
|
||||
questions: {
|
||||
algo: [],
|
||||
javascript: [],
|
||||
quiz: [],
|
||||
'system-design': ['image-carousel', 'dropdown-menu', 'modal-dialog'],
|
||||
'user-interface': [
|
||||
'accordion',
|
||||
'accordion-ii',
|
||||
'accordion-iii',
|
||||
'modal-dialog',
|
||||
'modal-dialog-ii',
|
||||
'modal-dialog-iii',
|
||||
'modal-dialog-iv',
|
||||
'tabs',
|
||||
'tabs-ii',
|
||||
'tabs-iii',
|
||||
'progress-bar',
|
||||
'star-rating',
|
||||
],
|
||||
},
|
||||
seo: {
|
||||
description: intl.formatMessage({
|
||||
defaultMessage:
|
||||
'Practice design system components interview questions, including Tabs, Modals, Accordions, and Progress Bars. Code in-browser with solutions from ex-interviewers.',
|
||||
description: 'Description for interview preparation focus area',
|
||||
id: 'geKY+2',
|
||||
}),
|
||||
socialTitle: intl.formatMessage({
|
||||
defaultMessage:
|
||||
'Design System Components Interview Questions | GreatFrontEnd',
|
||||
description: 'Social title for interview preparation focus area',
|
||||
id: 'xW6w5q',
|
||||
}),
|
||||
title: intl.formatMessage({
|
||||
defaultMessage: 'Practice Design System Components Interview Questions',
|
||||
description: 'Title for interview preparation focus area',
|
||||
id: 'KyrxLW',
|
||||
}),
|
||||
},
|
||||
shortDescription: intl.formatMessage({
|
||||
defaultMessage:
|
||||
'Elevate your front-end skills by practicing the creation of front end design system components.',
|
||||
description: 'Description for interview preparation focus area',
|
||||
id: 'PGq6U8',
|
||||
}),
|
||||
type: 'design-system-components',
|
||||
};
|
||||
}
|
||||
|
||||
const gradient: ThemeGradient<'#FF5F6D', '#FFC371'> = {
|
||||
className: 'bg-[linear-gradient(133.77deg,_#FF5F6D_0%,_#FFC371_97.95%)]',
|
||||
endColor: '#FFC371',
|
||||
startColor: '#FF5F6D',
|
||||
};
|
||||
|
||||
export function getFocusAreaThemeDesignSystemComponents(): QuestionListTheme_DEPRECATED {
|
||||
return {
|
||||
gradient,
|
||||
iconOutline: RiDashboardLine,
|
||||
iconSolid: RiDashboardLine,
|
||||
};
|
||||
}
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
import { TbForms } from 'react-icons/tb';
|
||||
import type { IntlShape } from 'react-intl';
|
||||
|
||||
import type { QuestionListTheme_DEPRECATED } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import type { ThemeGradient } from '~/components/ui/theme';
|
||||
|
||||
import type { FocusArea_DEPRECATED } from '../FocusAreas';
|
||||
|
||||
export function getFocusAreaForms(intl: IntlShape): FocusArea_DEPRECATED {
|
||||
return {
|
||||
description: intl.formatMessage({
|
||||
defaultMessage: 'Targeted practice on Forms interview questions',
|
||||
description: 'Description for interview preparation focus area',
|
||||
id: 'sRPvHx',
|
||||
}),
|
||||
href: '/focus-areas/forms',
|
||||
longName: intl.formatMessage({
|
||||
defaultMessage: 'Forms',
|
||||
description: 'Name of focus area questions',
|
||||
id: 'YKZzqP',
|
||||
}),
|
||||
name: intl.formatMessage({
|
||||
defaultMessage: 'Forms',
|
||||
description: 'Name of focus area questions',
|
||||
id: 'YKZzqP',
|
||||
}),
|
||||
questions: {
|
||||
algo: [],
|
||||
javascript: [],
|
||||
quiz: [],
|
||||
'system-design': ['e-commerce-amazon'],
|
||||
'user-interface': [
|
||||
'auth-code-input',
|
||||
'contact-form',
|
||||
'flight-booker',
|
||||
'mortgage-calculator',
|
||||
'nested-checkboxes',
|
||||
'signup-form',
|
||||
'todo-list',
|
||||
'temperature-converter',
|
||||
'transfer-list-ii',
|
||||
],
|
||||
},
|
||||
seo: {
|
||||
description: intl.formatMessage({
|
||||
defaultMessage:
|
||||
'Practice form-related interview questions on form components, validation, and submission handling. Code in-browser with solutions from ex-interviewers.',
|
||||
description: 'Description for interview preparation focus area',
|
||||
id: '9kGiQx',
|
||||
}),
|
||||
socialTitle: intl.formatMessage({
|
||||
defaultMessage: 'Forms Interview Questions | GreatFrontEnd',
|
||||
description: 'Social title for interview preparation focus area',
|
||||
id: 'pyOncc',
|
||||
}),
|
||||
title: intl.formatMessage({
|
||||
defaultMessage: 'Practice Forms Interview Questions with Solutions',
|
||||
description: 'Title for interview preparation focus area',
|
||||
id: '65GCar',
|
||||
}),
|
||||
},
|
||||
shortDescription: intl.formatMessage({
|
||||
defaultMessage:
|
||||
'Master the art of building interactive and user-friendly forms.',
|
||||
description: 'Description for interview preparation focus area',
|
||||
id: 'DbEF7d',
|
||||
}),
|
||||
type: 'forms',
|
||||
};
|
||||
}
|
||||
|
||||
const gradient: ThemeGradient<'#56ab2f', '#a8e063'> = {
|
||||
className: 'bg-[linear-gradient(133.77deg,_#56ab2f_0%,_#a8e063_97.95%)]',
|
||||
endColor: '#a8e063',
|
||||
startColor: '#56ab2f',
|
||||
};
|
||||
|
||||
export function getFocusAreaThemeForms(): QuestionListTheme_DEPRECATED {
|
||||
return {
|
||||
gradient,
|
||||
iconOutline: TbForms,
|
||||
iconSolid: TbForms,
|
||||
};
|
||||
}
|
||||
|
|
@ -1,106 +0,0 @@
|
|||
import { RiJavascriptFill } from 'react-icons/ri';
|
||||
import type { IntlShape } from 'react-intl';
|
||||
|
||||
import type { QuestionListTheme_DEPRECATED } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import type { ThemeGradient } from '~/components/ui/theme';
|
||||
|
||||
import type { FocusArea_DEPRECATED } from '../FocusAreas';
|
||||
|
||||
export function getFocusAreaJavaScriptPolyfills(
|
||||
intl: IntlShape,
|
||||
): FocusArea_DEPRECATED {
|
||||
return {
|
||||
description: intl.formatMessage({
|
||||
defaultMessage:
|
||||
'Targeted practice on JavaScript Polyfills interview questions',
|
||||
description: 'Description for interview preparation focus area',
|
||||
id: '7+uXHt',
|
||||
}),
|
||||
href: '/focus-areas/javascript-polyfills',
|
||||
longName: intl.formatMessage({
|
||||
defaultMessage: 'JavaScript Polyfills',
|
||||
description: 'Name of focus area questions',
|
||||
id: '9Q8e4/',
|
||||
}),
|
||||
name: intl.formatMessage({
|
||||
defaultMessage: 'JavaScript Polyfills',
|
||||
description: 'Name of focus area questions',
|
||||
id: '9Q8e4/',
|
||||
}),
|
||||
questions: {
|
||||
algo: [],
|
||||
javascript: [
|
||||
'array-at',
|
||||
'array-concat',
|
||||
'array-filter',
|
||||
'array-map',
|
||||
'array-reduce',
|
||||
'event-emitter',
|
||||
'event-emitter-ii',
|
||||
'find-index',
|
||||
'find-last-index',
|
||||
'flatten',
|
||||
'function-apply',
|
||||
'function-bind',
|
||||
'function-call',
|
||||
'get-elements-by-class-name',
|
||||
'get-elements-by-tag-name',
|
||||
'get-elements-by-tag-name-hierarchy',
|
||||
'json-stringify',
|
||||
'promise-all',
|
||||
'promise-all-settled',
|
||||
'promise-any',
|
||||
'promise-race',
|
||||
'promise-reject',
|
||||
'promise-resolve',
|
||||
'promise-with-resolvers',
|
||||
'type-utilities',
|
||||
'type-utilities-ii',
|
||||
],
|
||||
quiz: [],
|
||||
'system-design': [],
|
||||
'user-interface': [],
|
||||
},
|
||||
seo: {
|
||||
description: intl.formatMessage({
|
||||
defaultMessage:
|
||||
'Practice JavaScript Polyfills interview questions by implementing JS and DOM APIs from scratch. Code in-browser with solutions by ex-interviewers.',
|
||||
description: 'Description for interview preparation focus area',
|
||||
id: 'LmjB8K',
|
||||
}),
|
||||
socialTitle: intl.formatMessage({
|
||||
defaultMessage:
|
||||
'JavaScript Polyfills Interview Questions | GreatFrontEnd',
|
||||
description: 'Social title for interview preparation focus area',
|
||||
id: '30sSdR',
|
||||
}),
|
||||
title: intl.formatMessage({
|
||||
defaultMessage:
|
||||
'Practice JavaScript Polyfills Interview Questions with Solutions',
|
||||
description: 'Title for interview preparation focus area',
|
||||
id: '7aqW08',
|
||||
}),
|
||||
},
|
||||
shortDescription: intl.formatMessage({
|
||||
defaultMessage:
|
||||
'Gain proficiency in front end fundamentals by implementing JavaScript and DOM APIs from scratch.',
|
||||
description: 'Description for interview preparation focus area',
|
||||
id: 'YGqz7y',
|
||||
}),
|
||||
type: 'javascript-polyfills',
|
||||
};
|
||||
}
|
||||
|
||||
const gradient: ThemeGradient<'#f7df1e', '#f7df1e'> = {
|
||||
className: 'bg-[linear-gradient(133.77deg,_#f7df1e_0%,_#f7df1e_97.95%)]',
|
||||
endColor: '#f7df1e',
|
||||
startColor: '#f7df1e',
|
||||
};
|
||||
|
||||
export function getFocusAreaThemeJavaScriptPolyfills(): QuestionListTheme_DEPRECATED {
|
||||
return {
|
||||
gradient,
|
||||
iconOutline: RiJavascriptFill,
|
||||
iconSolid: RiJavascriptFill,
|
||||
};
|
||||
}
|
||||
|
|
@ -1,105 +0,0 @@
|
|||
import { SiLodash } from 'react-icons/si';
|
||||
import type { IntlShape } from 'react-intl';
|
||||
|
||||
import type { QuestionListTheme_DEPRECATED } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import type { ThemeGradient } from '~/components/ui/theme';
|
||||
|
||||
import type { FocusArea_DEPRECATED } from '../FocusAreas';
|
||||
|
||||
export function getFocusAreaLodash(intl: IntlShape): FocusArea_DEPRECATED {
|
||||
return {
|
||||
description: intl.formatMessage({
|
||||
defaultMessage:
|
||||
'Targeted practice on Lodash Functions interview questions',
|
||||
description: 'Description for interview preparation focus area',
|
||||
id: 'EDmnjv',
|
||||
}),
|
||||
href: '/focus-areas/lodash',
|
||||
longName: intl.formatMessage({
|
||||
defaultMessage: 'Lodash Functions',
|
||||
description: 'Name of focus area questions',
|
||||
id: '0HOYxB',
|
||||
}),
|
||||
name: intl.formatMessage({
|
||||
defaultMessage: 'Lodash Functions',
|
||||
description: 'Name of focus area questions',
|
||||
id: '0HOYxB',
|
||||
}),
|
||||
questions: {
|
||||
algo: [],
|
||||
javascript: [
|
||||
'chunk',
|
||||
'clamp',
|
||||
'compact',
|
||||
'count-by',
|
||||
'curry',
|
||||
'debounce',
|
||||
'deep-clone',
|
||||
'deep-equal',
|
||||
'difference',
|
||||
'drop-right-while',
|
||||
'drop-while',
|
||||
'fill',
|
||||
'find-index',
|
||||
'find-last-index',
|
||||
'flatten',
|
||||
'from-pairs',
|
||||
'get',
|
||||
'group-by',
|
||||
'in-range',
|
||||
'intersection',
|
||||
'intersection-by',
|
||||
'intersection-with',
|
||||
'is-empty',
|
||||
'limit',
|
||||
'once',
|
||||
'size',
|
||||
'throttle',
|
||||
'unique-array',
|
||||
],
|
||||
// Use question importance for now.
|
||||
quiz: [],
|
||||
'system-design': [],
|
||||
'user-interface': [],
|
||||
},
|
||||
seo: {
|
||||
description: intl.formatMessage({
|
||||
defaultMessage:
|
||||
'Practice Lodash interview questions, implementing functions to manipulate and transform data efficiently. Code in-browser with solutions from ex-interviewers.',
|
||||
description: 'Description for interview preparation focus area',
|
||||
id: 'ANgYyn',
|
||||
}),
|
||||
socialTitle: intl.formatMessage({
|
||||
defaultMessage: 'Lodash Functions Interview Questions | GreatFrontEnd',
|
||||
description: 'Title for interview preparation focus area',
|
||||
id: 'qbj/DA',
|
||||
}),
|
||||
title: intl.formatMessage({
|
||||
defaultMessage: 'Practice Lodash Interview Questions with Solutions',
|
||||
description: 'Title for interview preparation focus area',
|
||||
id: '97VOmx',
|
||||
}),
|
||||
},
|
||||
shortDescription: intl.formatMessage({
|
||||
defaultMessage:
|
||||
'Strengthen your proficiency in JavaScript through writing Lodash functions from scratch.',
|
||||
description: 'Description for interview preparation focus area',
|
||||
id: 'NoFZV/',
|
||||
}),
|
||||
type: 'lodash',
|
||||
};
|
||||
}
|
||||
|
||||
const gradient: ThemeGradient<'#7474BF', '#348AC7'> = {
|
||||
className: 'bg-[linear-gradient(133.77deg,_#7474BF_0%,_#348AC7_97.95%)]',
|
||||
endColor: '#348AC7',
|
||||
startColor: '#7474BF',
|
||||
};
|
||||
|
||||
export function getFocusAreaThemeLodash(): QuestionListTheme_DEPRECATED {
|
||||
return {
|
||||
gradient,
|
||||
iconOutline: SiLodash,
|
||||
iconSolid: SiLodash,
|
||||
};
|
||||
}
|
||||
|
|
@ -1,96 +0,0 @@
|
|||
import { RiFlowChart } from 'react-icons/ri';
|
||||
import type { IntlShape } from 'react-intl';
|
||||
|
||||
import type { QuestionListTheme_DEPRECATED } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import type { ThemeGradient } from '~/components/ui/theme';
|
||||
|
||||
import type { FocusArea_DEPRECATED } from '../FocusAreas';
|
||||
|
||||
export function getFocusAreaStateManagement(
|
||||
intl: IntlShape,
|
||||
): FocusArea_DEPRECATED {
|
||||
return {
|
||||
description: intl.formatMessage({
|
||||
defaultMessage:
|
||||
'Targeted practice on State Management interview questions',
|
||||
description: 'Description for interview preparation focus area',
|
||||
id: 'yztOsj',
|
||||
}),
|
||||
href: '/focus-areas/state-management',
|
||||
longName: intl.formatMessage({
|
||||
defaultMessage: 'State Management',
|
||||
description: 'Name of focus area questions',
|
||||
id: '7xPEg+',
|
||||
}),
|
||||
name: intl.formatMessage({
|
||||
defaultMessage: 'State Management',
|
||||
description: 'Name of focus area questions',
|
||||
id: '7xPEg+',
|
||||
}),
|
||||
questions: {
|
||||
algo: [],
|
||||
javascript: [],
|
||||
quiz: [],
|
||||
'system-design': [],
|
||||
'user-interface': [
|
||||
'connect-four',
|
||||
'data-table',
|
||||
'data-table-ii',
|
||||
'data-table-iii',
|
||||
'data-table-iv',
|
||||
'grid-lights',
|
||||
'image-carousel-ii',
|
||||
'image-carousel-iii',
|
||||
'memory-game',
|
||||
'nested-checkboxes',
|
||||
'pixel-art',
|
||||
'transfer-list',
|
||||
'transfer-list-ii',
|
||||
'undoable-counter',
|
||||
'users-database',
|
||||
'whack-a-mole',
|
||||
'wordle',
|
||||
],
|
||||
},
|
||||
seo: {
|
||||
description: intl.formatMessage({
|
||||
defaultMessage:
|
||||
'Practice State Management interview questions that train your skills in complex state design and state manipulation. Code in-browser with solutions from ex-interviewers.',
|
||||
description: 'Description for interview preparation focus area',
|
||||
id: '4GPc8y',
|
||||
}),
|
||||
socialTitle: intl.formatMessage({
|
||||
defaultMessage: 'State Management Interview Questions | GreatFrontEnd',
|
||||
description: 'Social title for interview preparation focus area',
|
||||
id: '9Ct+/8',
|
||||
}),
|
||||
title: intl.formatMessage({
|
||||
defaultMessage:
|
||||
'Practice State Management Interview Questions with Solutions',
|
||||
description: 'Title for interview preparation focus area',
|
||||
id: 'hLuz6h',
|
||||
}),
|
||||
},
|
||||
shortDescription: intl.formatMessage({
|
||||
defaultMessage:
|
||||
'Train your skills in designing complex state and implementing operations to manipulate state.',
|
||||
description: 'Description for interview preparation focus area',
|
||||
id: 's8/47i',
|
||||
}),
|
||||
type: 'state-management',
|
||||
};
|
||||
}
|
||||
|
||||
const gradient: ThemeGradient<'#4e54c8', '#8f94fb'> = {
|
||||
className: 'bg-[linear-gradient(133.77deg,_#4e54c8_0%,_#8f94fb_97.95%)]',
|
||||
endColor: '#8f94fb',
|
||||
startColor: '#4e54c8',
|
||||
};
|
||||
|
||||
export function getFocusAreaThemeStateManagement(): QuestionListTheme_DEPRECATED {
|
||||
return {
|
||||
gradient,
|
||||
iconOutline: RiFlowChart,
|
||||
iconSolid: RiFlowChart,
|
||||
};
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
import type {
|
||||
QuestionList_DEPRECATED,
|
||||
QuestionListTheme_DEPRECATED,
|
||||
} from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
|
||||
import { getFocusAreaThemes_DEPRECATED } from '../focus-areas/FocusAreas';
|
||||
import { useFocusAreas_DEPRECATED } from '../focus-areas/FocusAreasHooks';
|
||||
import { getPreparationPlanThemes } from '../plans/PreparationPlans';
|
||||
import { usePreparationPlans } from '../plans/PreparationPlansHooks';
|
||||
|
||||
export function useQuestionLists_DEPRECATED(): Record<
|
||||
string,
|
||||
QuestionList_DEPRECATED
|
||||
> {
|
||||
const plans = usePreparationPlans();
|
||||
const focusAreas = useFocusAreas_DEPRECATED();
|
||||
|
||||
return { ...plans, ...focusAreas };
|
||||
}
|
||||
|
||||
export function getQuestionListThemes(): Record<
|
||||
string,
|
||||
QuestionListTheme_DEPRECATED
|
||||
> {
|
||||
const planThemes = getPreparationPlanThemes();
|
||||
const focusAreaThemes = getFocusAreaThemes_DEPRECATED();
|
||||
|
||||
return { ...planThemes, ...focusAreaThemes };
|
||||
}
|
||||
|
|
@ -315,10 +315,6 @@
|
|||
"defaultMessage": "Cancel",
|
||||
"description": "Cancel button label"
|
||||
},
|
||||
"0HOYxB": {
|
||||
"defaultMessage": "Lodash Functions",
|
||||
"description": "Name of focus area questions"
|
||||
},
|
||||
"0IALGm": {
|
||||
"defaultMessage": "Hello {userEmail}!",
|
||||
"description": "Title of AuthPage when logged in"
|
||||
|
|
@ -515,10 +511,6 @@
|
|||
"defaultMessage": "Project progress",
|
||||
"description": "Project progress item label"
|
||||
},
|
||||
"1kiNiW": {
|
||||
"defaultMessage": "Accessibility",
|
||||
"description": "Name of focus area questions"
|
||||
},
|
||||
"1lAgj0": {
|
||||
"defaultMessage": "YOE / Job status",
|
||||
"description": "Label for experience filter for submissions list"
|
||||
|
|
@ -691,10 +683,6 @@
|
|||
"defaultMessage": "You replied to <recipientProfileLink>{recipient}</recipientProfileLink> on the challenge forum for <link>{challengeTitle}</link>: <comment>\"{description}\"</comment>",
|
||||
"description": "Log message for you replying to someone on the challenge forum"
|
||||
},
|
||||
"30sSdR": {
|
||||
"defaultMessage": "JavaScript Polyfills Interview Questions | GreatFrontEnd",
|
||||
"description": "Social title for interview preparation focus area"
|
||||
},
|
||||
"37Ttml": {
|
||||
"defaultMessage": "Security",
|
||||
"description": "Title for Security section on profile page"
|
||||
|
|
@ -863,10 +851,6 @@
|
|||
"defaultMessage": "Reset progress",
|
||||
"description": "Label to reset study plan progress"
|
||||
},
|
||||
"4GPc8y": {
|
||||
"defaultMessage": "Practice State Management interview questions that train your skills in complex state design and state manipulation. Code in-browser with solutions from ex-interviewers.",
|
||||
"description": "Description for interview preparation focus area"
|
||||
},
|
||||
"4KKeKQ": {
|
||||
"defaultMessage": "Syntax highlighting, theming and shortcuts",
|
||||
"description": "Label for item 3 for simulate real interviews section"
|
||||
|
|
@ -1099,10 +1083,6 @@
|
|||
"defaultMessage": "System Design",
|
||||
"description": "Tile for system design question type"
|
||||
},
|
||||
"65GCar": {
|
||||
"defaultMessage": "Practice Forms Interview Questions with Solutions",
|
||||
"description": "Title for interview preparation focus area"
|
||||
},
|
||||
"680b8U": {
|
||||
"defaultMessage": "Vanilla JS Questions",
|
||||
"description": "Vanilla JS questions category long title"
|
||||
|
|
@ -1255,10 +1235,6 @@
|
|||
"defaultMessage": "{commentsCount, plural, =0 {No comments} one {# comment} other {# comments}}",
|
||||
"description": "Number of comments for project submission"
|
||||
},
|
||||
"7+uXHt": {
|
||||
"defaultMessage": "Targeted practice on JavaScript Polyfills interview questions",
|
||||
"description": "Description for interview preparation focus area"
|
||||
},
|
||||
"7/se2x": {
|
||||
"defaultMessage": "{count}+ questions are free to do",
|
||||
"description": "Marketing page section subtitle"
|
||||
|
|
@ -1383,10 +1359,6 @@
|
|||
"defaultMessage": "Implementation must contain at least {minLength} character(s).",
|
||||
"description": "Error message"
|
||||
},
|
||||
"7aqW08": {
|
||||
"defaultMessage": "Practice JavaScript Polyfills Interview Questions with Solutions",
|
||||
"description": "Title for interview preparation focus area"
|
||||
},
|
||||
"7fCoNs": {
|
||||
"defaultMessage": "Will I have to code within the platform, or use my own IDE?",
|
||||
"description": "FAQ question for projects platform"
|
||||
|
|
@ -1435,10 +1407,6 @@
|
|||
"defaultMessage": "Practice Top HTML Front End Interview Questions with Solutions",
|
||||
"description": "SEO title for HTML questions list page"
|
||||
},
|
||||
"7xPEg+": {
|
||||
"defaultMessage": "State Management",
|
||||
"description": "Name of focus area questions"
|
||||
},
|
||||
"7xuDzw": {
|
||||
"defaultMessage": "We are also the only platform offering decent front end system design content.",
|
||||
"description": "FAQ answer"
|
||||
|
|
@ -1495,10 +1463,6 @@
|
|||
"defaultMessage": "Coming soon",
|
||||
"description": "Tooltip for Coming Soon questions label"
|
||||
},
|
||||
"8Luumm": {
|
||||
"defaultMessage": "Targeted practice on DOM Manipulation interview questions",
|
||||
"description": "Description for interview preparation focus area"
|
||||
},
|
||||
"8Nm9WZ": {
|
||||
"defaultMessage": "Walmart",
|
||||
"description": "Company name for Walmart"
|
||||
|
|
@ -1615,10 +1579,6 @@
|
|||
"defaultMessage": "Key features",
|
||||
"description": "Key features of the product"
|
||||
},
|
||||
"97VOmx": {
|
||||
"defaultMessage": "Practice Lodash Interview Questions with Solutions",
|
||||
"description": "Title for interview preparation focus area"
|
||||
},
|
||||
"99Ewym": {
|
||||
"defaultMessage": "Introduction",
|
||||
"description": "Front End interview preparation guide"
|
||||
|
|
@ -1639,10 +1599,6 @@
|
|||
"defaultMessage": "You have ended this project session. Returning you to the project detail page.",
|
||||
"description": "Toast subtitle for project session ended"
|
||||
},
|
||||
"9Ct+/8": {
|
||||
"defaultMessage": "State Management Interview Questions | GreatFrontEnd",
|
||||
"description": "Social title for interview preparation focus area"
|
||||
},
|
||||
"9D27sg": {
|
||||
"defaultMessage": "Discussions",
|
||||
"description": "Projects forum"
|
||||
|
|
@ -1683,10 +1639,6 @@
|
|||
"defaultMessage": "Tracks | Progress | {name}",
|
||||
"description": "Title of user profile progress tracks page"
|
||||
},
|
||||
"9Q8e4/": {
|
||||
"defaultMessage": "JavaScript Polyfills",
|
||||
"description": "Name of focus area questions"
|
||||
},
|
||||
"9RYs96": {
|
||||
"defaultMessage": "Review community submissions",
|
||||
"description": "Recommended action for new projects platform user"
|
||||
|
|
@ -1699,10 +1651,6 @@
|
|||
"defaultMessage": "Buy now",
|
||||
"description": "Purchase button label"
|
||||
},
|
||||
"9kGiQx": {
|
||||
"defaultMessage": "Practice form-related interview questions on form components, validation, and submission handling. Code in-browser with solutions from ex-interviewers.",
|
||||
"description": "Description for interview preparation focus area"
|
||||
},
|
||||
"9kkbE6": {
|
||||
"defaultMessage": "A simple yet comprehensive plan to follow",
|
||||
"description": "Title for marketing page study plans section"
|
||||
|
|
@ -1787,10 +1735,6 @@
|
|||
"defaultMessage": "Low",
|
||||
"description": "Low importance question"
|
||||
},
|
||||
"ANgYyn": {
|
||||
"defaultMessage": "Practice Lodash interview questions, implementing functions to manipulate and transform data efficiently. Code in-browser with solutions from ex-interviewers.",
|
||||
"description": "Description for interview preparation focus area"
|
||||
},
|
||||
"ATjflV": {
|
||||
"defaultMessage": "Choose up to 2 reasons so that we can improve your experience",
|
||||
"description": "Subtitle of motivation for joining section of projects profile edit page"
|
||||
|
|
@ -1827,10 +1771,6 @@
|
|||
"defaultMessage": "Use code at checkout",
|
||||
"description": "Instruction to apply discount"
|
||||
},
|
||||
"Adsxn4": {
|
||||
"defaultMessage": "Async Operations Interview Questions | GreatFrontEnd",
|
||||
"description": "Social title for interview preparation focus area"
|
||||
},
|
||||
"Ae22GD": {
|
||||
"defaultMessage": "Images just for illustration. Actual page(s) could be longer",
|
||||
"description": "Info for carousel images in project brief"
|
||||
|
|
@ -2255,10 +2195,6 @@
|
|||
"defaultMessage": "Premium question",
|
||||
"description": "Paywall title for premium questions feature"
|
||||
},
|
||||
"DbEF7d": {
|
||||
"defaultMessage": "Master the art of building interactive and user-friendly forms.",
|
||||
"description": "Description for interview preparation focus area"
|
||||
},
|
||||
"Dc5QrJ": {
|
||||
"defaultMessage": "Coding",
|
||||
"description": "Tile for coding question type"
|
||||
|
|
@ -2367,10 +2303,6 @@
|
|||
"defaultMessage": "There were some issues with taking a screenshot for your site. Please try again.",
|
||||
"description": "Error message for screenshot generation"
|
||||
},
|
||||
"EDmnjv": {
|
||||
"defaultMessage": "Targeted practice on Lodash Functions interview questions",
|
||||
"description": "Description for interview preparation focus area"
|
||||
},
|
||||
"EDnI5H": {
|
||||
"defaultMessage": "Expand to view all guides",
|
||||
"description": "Tooltip for expanded guide button"
|
||||
|
|
@ -2479,10 +2411,6 @@
|
|||
"defaultMessage": "Project started! Leverage the provided resources and submit a link to your site once ready!",
|
||||
"description": "Toast subtitle for project session started"
|
||||
},
|
||||
"EteZq/": {
|
||||
"defaultMessage": "Practice Data Structures and Algorithms Interview Questions",
|
||||
"description": "Title for interview preparation focus area"
|
||||
},
|
||||
"Euaee/": {
|
||||
"defaultMessage": "Resubscribe to unlock",
|
||||
"description": "Title for a premium project paywall"
|
||||
|
|
@ -2603,10 +2531,6 @@
|
|||
"defaultMessage": "Manage your subscription status and payment methods on the Stripe billing portal.",
|
||||
"description": "Call to action text to uppgrade plan."
|
||||
},
|
||||
"FwKG3p": {
|
||||
"defaultMessage": "Practice front end Accessibility interview questions on semantic HTML, ARIA, and screen readers. Code in-browser with curated solutions from ex-interviewers.",
|
||||
"description": "Description for interview preparation focus area"
|
||||
},
|
||||
"G+S25i": {
|
||||
"defaultMessage": "Language",
|
||||
"description": "Tooltip for language selector"
|
||||
|
|
@ -2699,10 +2623,6 @@
|
|||
"defaultMessage": "Welcome to GreatFrontEnd Projects!",
|
||||
"description": "Title for Projects onboarding page"
|
||||
},
|
||||
"GQfy69": {
|
||||
"defaultMessage": "Practice Accessibility Interview Questions with Solutions",
|
||||
"description": "Title for interview preparation focus area"
|
||||
},
|
||||
"GR83Ca": {
|
||||
"defaultMessage": "System",
|
||||
"description": "System color scheme option label"
|
||||
|
|
@ -2855,10 +2775,6 @@
|
|||
"defaultMessage": "Marked \"{articleName}\" as not completed",
|
||||
"description": "Success message shown when an article was marked as not completed"
|
||||
},
|
||||
"HMJJLh": {
|
||||
"defaultMessage": "Hone your computer science fundamentals by implementing important data structures and algorithms from scratch.",
|
||||
"description": "Description for interview preparation focus area"
|
||||
},
|
||||
"HP/djb": {
|
||||
"defaultMessage": "Experience | Settings",
|
||||
"description": "Title of experience (theme) settngs page"
|
||||
|
|
@ -3435,10 +3351,6 @@
|
|||
"defaultMessage": "Javascript Interview Guides",
|
||||
"description": "Title for guide card"
|
||||
},
|
||||
"KyrxLW": {
|
||||
"defaultMessage": "Practice Design System Components Interview Questions",
|
||||
"description": "Title for interview preparation focus area"
|
||||
},
|
||||
"L+jocg": {
|
||||
"defaultMessage": "View plans",
|
||||
"description": "View pricing plans"
|
||||
|
|
@ -3515,10 +3427,6 @@
|
|||
"defaultMessage": "Gamified learning",
|
||||
"description": "Title for \"Gamified learning\" feature on Projects home page"
|
||||
},
|
||||
"LGm3GF": {
|
||||
"defaultMessage": "Async Operations",
|
||||
"description": "Name of focus area questions"
|
||||
},
|
||||
"LKILl5": {
|
||||
"defaultMessage": "Submission successfully unpinned!",
|
||||
"description": "Submission unpin toaster"
|
||||
|
|
@ -3623,10 +3531,6 @@
|
|||
"defaultMessage": "Unlock challenge",
|
||||
"description": "Unlock premium access for a project"
|
||||
},
|
||||
"LmjB8K": {
|
||||
"defaultMessage": "Practice JavaScript Polyfills interview questions by implementing JS and DOM APIs from scratch. Code in-browser with solutions by ex-interviewers.",
|
||||
"description": "Description for interview preparation focus area"
|
||||
},
|
||||
"LmwfmQ": {
|
||||
"defaultMessage": "Front End System Design",
|
||||
"description": "Page title for System design question format page"
|
||||
|
|
@ -3939,10 +3843,6 @@
|
|||
"defaultMessage": "How we count contributions",
|
||||
"description": "Label for how we count contributions"
|
||||
},
|
||||
"NoFZV/": {
|
||||
"defaultMessage": "Strengthen your proficiency in JavaScript through writing Lodash functions from scratch.",
|
||||
"description": "Description for interview preparation focus area"
|
||||
},
|
||||
"Nt+P5A": {
|
||||
"defaultMessage": "Simulate real interview conditions, no need for any setup!",
|
||||
"description": "Subtitle for in-browser coding workspace feature"
|
||||
|
|
@ -4179,10 +4079,6 @@
|
|||
"defaultMessage": "3 Months Plan",
|
||||
"description": "Link to three months study plan"
|
||||
},
|
||||
"PGq6U8": {
|
||||
"defaultMessage": "Elevate your front-end skills by practicing the creation of front end design system components.",
|
||||
"description": "Description for interview preparation focus area"
|
||||
},
|
||||
"PHhUwD": {
|
||||
"defaultMessage": "Back to focus areas",
|
||||
"description": "Link text to navigate to focus areas list page"
|
||||
|
|
@ -4663,10 +4559,6 @@
|
|||
"defaultMessage": "Horizontal rule",
|
||||
"description": "Label for horizontal rule"
|
||||
},
|
||||
"RvPm3x": {
|
||||
"defaultMessage": "DOM Manipulation",
|
||||
"description": "Name of focus area questions"
|
||||
},
|
||||
"RxU5TE": {
|
||||
"defaultMessage": "Privacy policy",
|
||||
"description": "Link to privacy policy page"
|
||||
|
|
@ -4819,10 +4711,6 @@
|
|||
"defaultMessage": "Once you're done developing, follow this step-by-step guide to host your solution and submit the challenge.",
|
||||
"description": "Description for the project submission checklist section"
|
||||
},
|
||||
"Sj1CaY": {
|
||||
"defaultMessage": "Practice developing inclusive and accessible web experiences.",
|
||||
"description": "Description for interview preparation focus area"
|
||||
},
|
||||
"Sj7pMJ": {
|
||||
"defaultMessage": "<authorProfileLink>{author}</authorProfileLink> replied to <recipientProfileLink>{recipient}</recipientProfileLink> on the submission <link>{submissionTitle}</link>: <comment>\"{description}\"</comment>",
|
||||
"description": "Log message for someone replying to someone on a submission"
|
||||
|
|
@ -5127,10 +5015,6 @@
|
|||
"defaultMessage": "No result",
|
||||
"description": "Title for empty state when application of filters return no results"
|
||||
},
|
||||
"UrnJdy": {
|
||||
"defaultMessage": "Sharpen your skills in asynchronous programming by practicing the use of async/await, Promises, and callback functions.",
|
||||
"description": "Description for interview preparation focus area"
|
||||
},
|
||||
"Us7Uly": {
|
||||
"defaultMessage": "Ask us about it",
|
||||
"description": "Button that opens up mail for user to send us an email about their question about the Affiliate program"
|
||||
|
|
@ -5579,10 +5463,6 @@
|
|||
"defaultMessage": "Vue Coding Questions",
|
||||
"description": "Description for Vue questions title"
|
||||
},
|
||||
"XauDQh": {
|
||||
"defaultMessage": "Targeted practice on Accessibility interview questions",
|
||||
"description": "Description for interview preparation focus area"
|
||||
},
|
||||
"Xcw/lL": {
|
||||
"defaultMessage": "Explore user submissions handpicked for your growth - based on your profile, skills you're keen to learn, and the projects you've completed.",
|
||||
"description": "Page subtitle"
|
||||
|
|
@ -5623,10 +5503,6 @@
|
|||
"defaultMessage": "Suggests best projects for skill",
|
||||
"description": "Title of 'Recommended projects to build' sub-feature in Projects marketing page"
|
||||
},
|
||||
"Xs7UBt": {
|
||||
"defaultMessage": "Targeted practice on Async Operations interview questions",
|
||||
"description": "Description for interview preparation focus area"
|
||||
},
|
||||
"XtKx03": {
|
||||
"defaultMessage": "The definitive guide to preparing for Front End Interviews, written by the author of Front End Interview Handbook.",
|
||||
"description": "Front end interview guidebook description"
|
||||
|
|
@ -5691,10 +5567,6 @@
|
|||
"defaultMessage": "As mentioned above, there are many ways to host your project for free. Our recommend hosts are:",
|
||||
"description": "Text for Deployment Info in Projects"
|
||||
},
|
||||
"YGqz7y": {
|
||||
"defaultMessage": "Gain proficiency in front end fundamentals by implementing JavaScript and DOM APIs from scratch.",
|
||||
"description": "Description for interview preparation focus area"
|
||||
},
|
||||
"YIry1B": {
|
||||
"defaultMessage": "Pricing plans",
|
||||
"description": "Title for projects pricing plans"
|
||||
|
|
@ -5707,10 +5579,6 @@
|
|||
"defaultMessage": "Or reach us via these channels",
|
||||
"description": "Text to introduce users to alternative feedback channels"
|
||||
},
|
||||
"YKZzqP": {
|
||||
"defaultMessage": "Forms",
|
||||
"description": "Name of focus area questions"
|
||||
},
|
||||
"YM1bnf": {
|
||||
"defaultMessage": "An error has occurred",
|
||||
"description": "Title of alert indicating an error on Email Sign In/Up Page"
|
||||
|
|
@ -5899,10 +5767,6 @@
|
|||
"defaultMessage": "Since {date}",
|
||||
"description": "Since date for current project session card"
|
||||
},
|
||||
"ZcKmXM": {
|
||||
"defaultMessage": "Accessibility Interview Questions | GreatFrontEnd",
|
||||
"description": "Social title for interview preparation focus area"
|
||||
},
|
||||
"Zdojj9": {
|
||||
"defaultMessage": "Other",
|
||||
"description": "Label for \"Other\" onboarding option in Projects"
|
||||
|
|
@ -6771,10 +6635,6 @@
|
|||
"defaultMessage": "Project completed!",
|
||||
"description": "Success message"
|
||||
},
|
||||
"fDWt7h": {
|
||||
"defaultMessage": "Data Structures and Algorithms Interview Questions | GreatFrontEnd",
|
||||
"description": "Social title for interview preparation focus area"
|
||||
},
|
||||
"fEoTGW": {
|
||||
"defaultMessage": "Start a project",
|
||||
"description": "Label for Start a project button on Projects dashboard page"
|
||||
|
|
@ -7039,10 +6899,6 @@
|
|||
"defaultMessage": "<authorProfileLink>{author}</authorProfileLink> left a question on their submission <link>{submissionTitle}</link>: <comment>\"{description}\"</comment>",
|
||||
"description": "Log message for someone asking question on their submission"
|
||||
},
|
||||
"geKY+2": {
|
||||
"defaultMessage": "Practice design system components interview questions, including Tabs, Modals, Accordions, and Progress Bars. Code in-browser with solutions from ex-interviewers.",
|
||||
"description": "Description for interview preparation focus area"
|
||||
},
|
||||
"ghssuE": {
|
||||
"defaultMessage": "Next",
|
||||
"description": "Label for Next button on Projects profile onboarding page"
|
||||
|
|
@ -7151,10 +7007,6 @@
|
|||
"defaultMessage": "This date is too long ago to be possible. Please recheck your selections",
|
||||
"description": "Error message for invalid \"Month and year you started work as a Front End Engineer\" input on Projects profile onboarding page"
|
||||
},
|
||||
"hLuz6h": {
|
||||
"defaultMessage": "Practice State Management Interview Questions with Solutions",
|
||||
"description": "Title for interview preparation focus area"
|
||||
},
|
||||
"hMx0CX": {
|
||||
"defaultMessage": "Everything from the blog",
|
||||
"description": "Blog listing title for blog home page"
|
||||
|
|
@ -7659,10 +7511,6 @@
|
|||
"defaultMessage": "Step 3",
|
||||
"description": "Step N of multiple steps when completing a project"
|
||||
},
|
||||
"kWg+JN": {
|
||||
"defaultMessage": "Practice DOM manipulation interview questions on CSS selectors, DOM traversal, and element manipulation. Code in-browser with solutions from ex-interviewers.",
|
||||
"description": "Description for interview preparation focus area"
|
||||
},
|
||||
"kaEcHw": {
|
||||
"defaultMessage": "You've gained reputation points for signing up",
|
||||
"description": "Toast message about gaining reputation points"
|
||||
|
|
@ -7783,10 +7631,6 @@
|
|||
"defaultMessage": "Join Discord",
|
||||
"description": "Join Discord channel"
|
||||
},
|
||||
"l1pp5/": {
|
||||
"defaultMessage": "DOM Manipulation Interview Questions | GreatFrontEnd",
|
||||
"description": "Social title for interview preparation focus area"
|
||||
},
|
||||
"l27vTV": {
|
||||
"defaultMessage": "Back to all challenges",
|
||||
"description": "Back button label"
|
||||
|
|
@ -7875,10 +7719,6 @@
|
|||
"defaultMessage": "Cancel",
|
||||
"description": "Cancel button label in confirmation dialog"
|
||||
},
|
||||
"lf+GYY": {
|
||||
"defaultMessage": "Targeted practice on Data Structures & Algorithms interview questions",
|
||||
"description": "Description for interview preparation focus area"
|
||||
},
|
||||
"lfKH/E": {
|
||||
"defaultMessage": "Mark as complete",
|
||||
"description": "Mark the question as complete"
|
||||
|
|
@ -8091,10 +7931,6 @@
|
|||
"defaultMessage": "Basic details",
|
||||
"description": "Section title for user onboarding form"
|
||||
},
|
||||
"nQoQzP": {
|
||||
"defaultMessage": "Practice Async Operations Interview Questions with Solutions",
|
||||
"description": "Title for interview preparation focus area"
|
||||
},
|
||||
"nRFkBV": {
|
||||
"defaultMessage": "Create a free account to track your progress",
|
||||
"description": "Title for overlay on Projects dashboard page"
|
||||
|
|
@ -8199,10 +8035,6 @@
|
|||
"defaultMessage": "Session status",
|
||||
"description": "Completed and in progress challenges"
|
||||
},
|
||||
"o4CKFi": {
|
||||
"defaultMessage": "Practice DOM Manipulation Interview Questions with Solutions",
|
||||
"description": "Title for interview preparation focus area"
|
||||
},
|
||||
"o8bpfE": {
|
||||
"defaultMessage": "Front end interview questions",
|
||||
"description": "Title of all practice questions page"
|
||||
|
|
@ -8295,10 +8127,6 @@
|
|||
"defaultMessage": "Optimized preparation for target companies, leveraging insider tips and expertise.",
|
||||
"description": "Description for company guides page"
|
||||
},
|
||||
"onNjnt": {
|
||||
"defaultMessage": "Design System Components",
|
||||
"description": "Name of focus area questions"
|
||||
},
|
||||
"oo7GzR": {
|
||||
"defaultMessage": "Menu",
|
||||
"description": "Guides navbar menu button label"
|
||||
|
|
@ -8495,10 +8323,6 @@
|
|||
"defaultMessage": "Top Svelte coding interview questions to build the most commonly-asked front end UI components and applications.",
|
||||
"description": "Description for Svelte questions page"
|
||||
},
|
||||
"pyOncc": {
|
||||
"defaultMessage": "Forms Interview Questions | GreatFrontEnd",
|
||||
"description": "Social title for interview preparation focus area"
|
||||
},
|
||||
"pz1v44": {
|
||||
"defaultMessage": "Next",
|
||||
"description": "Next button label"
|
||||
|
|
@ -8607,10 +8431,6 @@
|
|||
"defaultMessage": "Trending user submissions",
|
||||
"description": "Title for Trending submissions section on Projects dashboard page"
|
||||
},
|
||||
"qZRTqi": {
|
||||
"defaultMessage": "Data Structures & Algorithms",
|
||||
"description": "Name of focus area questions"
|
||||
},
|
||||
"qZTabX": {
|
||||
"defaultMessage": "Code in browser",
|
||||
"description": "Features for interviews questions"
|
||||
|
|
@ -8619,10 +8439,6 @@
|
|||
"defaultMessage": "First time preparing for front end interviews?",
|
||||
"description": "Link to front end interview guidebook"
|
||||
},
|
||||
"qbj/DA": {
|
||||
"defaultMessage": "Lodash Functions Interview Questions | GreatFrontEnd",
|
||||
"description": "Title for interview preparation focus area"
|
||||
},
|
||||
"qdOBuk": {
|
||||
"defaultMessage": "Practice questions",
|
||||
"description": "Section title"
|
||||
|
|
@ -8815,10 +8631,6 @@
|
|||
"defaultMessage": "Explore study plans that help you prepare for your front end interviews regardless of time left. Efficiently focus on topics that give you the most mileage for time.",
|
||||
"description": "Page description for study plans listing"
|
||||
},
|
||||
"s8/47i": {
|
||||
"defaultMessage": "Train your skills in designing complex state and implementing operations to manipulate state.",
|
||||
"description": "Description for interview preparation focus area"
|
||||
},
|
||||
"sCpKTY": {
|
||||
"defaultMessage": "Billing | Settings",
|
||||
"description": "Title of billing page"
|
||||
|
|
@ -8851,10 +8663,6 @@
|
|||
"defaultMessage": "+{count} more",
|
||||
"description": "Label for number of additional skills"
|
||||
},
|
||||
"sRPvHx": {
|
||||
"defaultMessage": "Targeted practice on Forms interview questions",
|
||||
"description": "Description for interview preparation focus area"
|
||||
},
|
||||
"sU6jXI": {
|
||||
"defaultMessage": "Reputation you have gained from completing challenges using this skill, including challenges not in the recommended skill plan",
|
||||
"description": "Tooltip for reputation label"
|
||||
|
|
@ -8979,10 +8787,6 @@
|
|||
"defaultMessage": "Link Title",
|
||||
"description": "Label for link title"
|
||||
},
|
||||
"t55S7k": {
|
||||
"defaultMessage": "Targeted practice on Design System Components interview questions",
|
||||
"description": "Description for interview preparation focus area"
|
||||
},
|
||||
"t5L0yE": {
|
||||
"defaultMessage": "Pricing",
|
||||
"description": "Link to pricing plans page"
|
||||
|
|
@ -9263,10 +9067,6 @@
|
|||
"defaultMessage": "Sign in to your account",
|
||||
"description": "Subtitle of Sign In page"
|
||||
},
|
||||
"urxhTe": {
|
||||
"defaultMessage": "Practice data structures and algorithms interview questions in-browser with JavaScript / TypeScript solutions from ex-interviewers",
|
||||
"description": "Description for interview preparation focus area"
|
||||
},
|
||||
"ut9h+K": {
|
||||
"defaultMessage": "You have <bold>{amountLeft}</bold>/{totalAmount} premium credits remaining. Unlock this challenge to learn from user submissions for premium challenges.",
|
||||
"description": "Subtitle for project paywall"
|
||||
|
|
@ -9383,10 +9183,6 @@
|
|||
"defaultMessage": "Clarify any doubts on a project in project-specific forums",
|
||||
"description": "Description for \"Learn from others\" feature on Projects home page"
|
||||
},
|
||||
"vccqVg": {
|
||||
"defaultMessage": "Practice async operations interview questions on async / await, Promises, and callbacks. Code in-browser with quality solutions and tests from ex-interviewers.",
|
||||
"description": "Description for interview preparation focus area"
|
||||
},
|
||||
"vegaR1": {
|
||||
"defaultMessage": "Sort by",
|
||||
"description": "Label for sorting button"
|
||||
|
|
@ -9647,10 +9443,6 @@
|
|||
"defaultMessage": "3 subcategories of questions: JavaScript, User Interfaces & Data Structures and Algorithms",
|
||||
"description": "Description of coding interview preparation"
|
||||
},
|
||||
"xW6w5q": {
|
||||
"defaultMessage": "Design System Components Interview Questions | GreatFrontEnd",
|
||||
"description": "Social title for interview preparation focus area"
|
||||
},
|
||||
"xWAt8Q": {
|
||||
"defaultMessage": "The ultimate Front End Interview preparation platform.",
|
||||
"description": "Description of GreatFrontEnd page"
|
||||
|
|
@ -9767,10 +9559,6 @@
|
|||
"defaultMessage": "Reading time",
|
||||
"description": "Reading time of the article"
|
||||
},
|
||||
"yAJsl0": {
|
||||
"defaultMessage": "Familiarize with selecting elements using CSS selectors, traverse the DOM hierarchy, and manipulate their properties, content, and styles.",
|
||||
"description": "Description for interview preparation focus area"
|
||||
},
|
||||
"yC3EoK": {
|
||||
"defaultMessage": "Practice JavaScript coding interview questions by implementing utility functions like throttle or polyfills. Code in-browser with solutions from ex-interviewers.",
|
||||
"description": "SEO description for Javascript coding question format page"
|
||||
|
|
@ -9875,10 +9663,6 @@
|
|||
"defaultMessage": "Unlike other challenge platforms, all our projects are modular with one other as they are constructed with the same design system. Easily mix and match any component or project you build to craft a unique app.",
|
||||
"description": "Description of 'Personalized projects' feature in Projects marketing page"
|
||||
},
|
||||
"yztOsj": {
|
||||
"defaultMessage": "Targeted practice on State Management interview questions",
|
||||
"description": "Description for interview preparation focus area"
|
||||
},
|
||||
"z+5YJV": {
|
||||
"defaultMessage": "View All Questions",
|
||||
"description": "Link label to the list of all User Interface coding questions"
|
||||
|
|
|
|||
Loading…
Reference in New Issue