[web] interviews/learning-list: deprecate focus area methods
This commit is contained in:
parent
bc9b18fbde
commit
f2e505d0d8
|
|
@ -1,56 +1,5 @@
|
|||
// @ts-check
|
||||
|
||||
import { makeSource } from 'contentlayer/source-files';
|
||||
import remarkFrontmatter from 'remark-frontmatter';
|
||||
import remarkGfm from 'remark-gfm';
|
||||
import remarkMdxFrontmatter from 'remark-mdx-frontmatter';
|
||||
import config from './src/content/contentlayerConfig';
|
||||
|
||||
import { BlogAuthorDocument } from './src/components/blog/contentlayer/BlogAuthorDocument';
|
||||
import { BlogCategoryDocument } from './src/components/blog/contentlayer/BlogCategoryDocument';
|
||||
import { BlogPostDocument } from './src/components/blog/contentlayer/BlogPostDocument';
|
||||
import { BlogSeriesDocument } from './src/components/blog/contentlayer/BlogSeriesDocument';
|
||||
import { BlogSubseriesDocument } from './src/components/blog/contentlayer/BlogSubseriesDocument';
|
||||
import { ProjectsCommonGuideDocument } from './src/components/projects/contentlayer/ProjectsCommonGuideDocument';
|
||||
import { ProjectsChallengeAppendixDocument } from './src/components/projects/contentlayer/ProjectsChallengeAppendixDocument';
|
||||
import { ProjectsChallengeBriefDocument } from './src/components/projects/contentlayer/ProjectsChallengeBriefDocument';
|
||||
import { ProjectsChallengeInfoDocument } from './src/components/projects/contentlayer/ProjectsChallengeInfoDocument';
|
||||
import { ProjectsChallengeMetadataDocument } from './src/components/projects/contentlayer/ProjectsChallengeMetadataDocument';
|
||||
import { ProjectsChallengeStyleGuideDocument } from './src/components/projects/contentlayer/ProjectsChallengeStyleGuideDocument';
|
||||
import { ProjectsChallengeGuideDocument } from './src/components/projects/contentlayer/ProjectsChallengeGuideDocument';
|
||||
import { ProjectsChallengeAPIWriteupDocument } from './src/components/projects/contentlayer/ProjectsChallengeAPIWriteupDocument';
|
||||
import { ProjectsTrackMetadataDocument } from './src/components/projects/contentlayer/ProjectsTrackMetadataDocument';
|
||||
import { ProjectsTrackInfoDocument } from './src/components/projects/contentlayer/ProjectsTrackInfoDocument';
|
||||
import { ProjectsSkillMetadataDocument } from './src/components/projects/contentlayer/ProjectsSkillMetadataDocument';
|
||||
import { ProjectsSkillInfoDocument } from './src/components/projects/contentlayer/ProjectsSkillInfoDocument';
|
||||
import { JobsPostingDocument } from './src/components/hiring/contentlayer/JobsPostingDocument.ts';
|
||||
import { InterviewsLearningListDocument } from './src/components/interviews/questions/listings/learning/InterviewsLearningListDocument.ts';
|
||||
import { InterviewsListingBottomContentDocument } from './src/components/interviews/company/contentlayer/InterviewsListingBottomContentDocument.ts';
|
||||
|
||||
export default makeSource({
|
||||
contentDirPath: 'src/content',
|
||||
documentTypes: [
|
||||
BlogAuthorDocument,
|
||||
BlogCategoryDocument,
|
||||
BlogPostDocument,
|
||||
BlogSeriesDocument,
|
||||
BlogSubseriesDocument,
|
||||
InterviewsLearningListDocument,
|
||||
InterviewsListingBottomContentDocument,
|
||||
ProjectsCommonGuideDocument,
|
||||
ProjectsChallengeAppendixDocument,
|
||||
ProjectsChallengeBriefDocument,
|
||||
ProjectsChallengeGuideDocument,
|
||||
ProjectsChallengeInfoDocument,
|
||||
ProjectsChallengeMetadataDocument,
|
||||
ProjectsChallengeStyleGuideDocument,
|
||||
ProjectsChallengeAPIWriteupDocument,
|
||||
ProjectsSkillMetadataDocument,
|
||||
ProjectsSkillInfoDocument,
|
||||
ProjectsTrackMetadataDocument,
|
||||
ProjectsTrackInfoDocument,
|
||||
JobsPostingDocument,
|
||||
],
|
||||
mdx: {
|
||||
remarkPlugins: [remarkGfm, remarkFrontmatter, remarkMdxFrontmatter],
|
||||
},
|
||||
});
|
||||
export default config;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
'use client';
|
||||
|
||||
import type { InterviewsLearningList } from 'contentlayer/generated';
|
||||
import type { InterviewsStudyList } from 'contentlayer/generated';
|
||||
import { useInView } from 'framer-motion';
|
||||
import dynamic from 'next/dynamic';
|
||||
import { useRef } from 'react';
|
||||
|
|
@ -15,7 +15,7 @@ const InterviewsMarketingHomePageBottomNew = dynamic(
|
|||
);
|
||||
|
||||
type Props = Readonly<{
|
||||
companyGuides: ReadonlyArray<InterviewsLearningList>;
|
||||
companyGuides: ReadonlyArray<InterviewsStudyList>;
|
||||
questions: QuestionBankDataType;
|
||||
}>;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import type { InterviewsLearningList } from 'contentlayer/generated';
|
||||
import type { InterviewsStudyList } from 'contentlayer/generated';
|
||||
|
||||
import { useUserProfile } from '~/components/global/UserProfileProvider';
|
||||
import InterviewsMarketingCompaniesSection from '~/components/interviews/marketing/InterviewsMarketingCompaniesSection';
|
||||
|
|
@ -15,7 +15,7 @@ import InterviewsPricingSectionLocalizedContainer from '~/components/interviews/
|
|||
import MarketingCommunitySection from '~/components/marketing/contact/MarketingCommunitySection';
|
||||
|
||||
type Props = Readonly<{
|
||||
companyGuides: ReadonlyArray<InterviewsLearningList>;
|
||||
companyGuides: ReadonlyArray<InterviewsStudyList>;
|
||||
questions: QuestionBankDataType;
|
||||
}>;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import type { InterviewsLearningList } from 'contentlayer/generated';
|
||||
import type { InterviewsStudyList } from 'contentlayer/generated';
|
||||
|
||||
import InterviewsMarketingEmbedSection from '~/components/interviews/marketing/embed/InterviewsMarketingEmbedSection';
|
||||
import type { EmbedUIQuestion } from '~/components/interviews/marketing/embed/InterviewsMarketingEmbedUIQuestion';
|
||||
|
|
@ -15,7 +15,7 @@ import Section from '~/components/ui/Heading/HeadingContext';
|
|||
import InterviewsMarketingHomePageBottomContainer from './InterviewsMarketingHomePageBottomContainer';
|
||||
|
||||
type Props = Readonly<{
|
||||
companyGuides: ReadonlyArray<InterviewsLearningList>;
|
||||
companyGuides: ReadonlyArray<InterviewsStudyList>;
|
||||
javaScriptEmbedExample: QuestionJavaScript;
|
||||
questions: QuestionBankDataType;
|
||||
testimonials: ReadonlyArray<InterviewsMarketingTestimonial>;
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import {
|
|||
} from '~/components/interviews/questions/listings/filters/QuestionsProcessor';
|
||||
import { QuestionCount } from '~/components/interviews/questions/listings/stats/QuestionCount';
|
||||
|
||||
import { fetchInterviewsLearningLists } from '~/db/contentlayer/InterviewsLearningListReader';
|
||||
import { fetchInterviewsStudyLists } from '~/db/contentlayer/InterviewsStudyListReader';
|
||||
import {
|
||||
readQuestionJavaScriptContents,
|
||||
readQuestionUserInterface,
|
||||
|
|
@ -220,7 +220,7 @@ export default async function Page({ params }: Props) {
|
|||
fetchQuestionsListQuiz(locale),
|
||||
fetchQuestionsListSystemDesign(locale),
|
||||
// Company guides
|
||||
fetchInterviewsLearningLists('company'),
|
||||
fetchInterviewsStudyLists('company'),
|
||||
]);
|
||||
|
||||
const testimonials = InterviewsMarketingTestimonialsDict();
|
||||
|
|
|
|||
|
|
@ -1,175 +0,0 @@
|
|||
'use client';
|
||||
|
||||
import clsx from 'clsx';
|
||||
import { RiArrowRightLine } from 'react-icons/ri';
|
||||
|
||||
import { trpc } from '~/hooks/trpc';
|
||||
|
||||
import type {
|
||||
FocusArea,
|
||||
FocusAreas,
|
||||
FocusAreaType,
|
||||
} from '~/data/focus-areas/FocusAreas';
|
||||
import { getFocusAreaTheme } from '~/data/focus-areas/FocusAreas';
|
||||
|
||||
import type { QuestionDifficulty } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import CompletionCountSummary from '~/components/interviews/questions/listings/stats/CompletionCountSummary';
|
||||
import QuestionCountLabel from '~/components/interviews/questions/metadata/QuestionCountLabel';
|
||||
import QuestionDifficultySummary from '~/components/interviews/questions/metadata/QuestionDifficultySummary';
|
||||
import { useIntl } from '~/components/intl';
|
||||
import Anchor from '~/components/ui/Anchor';
|
||||
import Badge from '~/components/ui/Badge';
|
||||
import Container from '~/components/ui/Container';
|
||||
import Heading from '~/components/ui/Heading';
|
||||
import Section from '~/components/ui/Heading/HeadingContext';
|
||||
import Text from '~/components/ui/Text';
|
||||
import { themeGlassyBorder } from '~/components/ui/theme';
|
||||
|
||||
import { countNumberOfQuestionsInList } from '~/db/QuestionsUtils';
|
||||
|
||||
import { useUser } from '@supabase/auth-helpers-react';
|
||||
|
||||
function FocusAreaCard({
|
||||
difficultySummary,
|
||||
area: { type, name, shortDescription, questions, href },
|
||||
isStarted = false,
|
||||
completionCount = 0,
|
||||
}: {
|
||||
area: FocusArea;
|
||||
completionCount?: number;
|
||||
difficultySummary: Record<QuestionDifficulty, number>;
|
||||
isStarted?: boolean;
|
||||
}) {
|
||||
const intl = useIntl();
|
||||
const questionCount = countNumberOfQuestionsInList(questions);
|
||||
const theme = getFocusAreaTheme(type);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
'group relative flex flex-1 items-center gap-6 rounded-lg p-4',
|
||||
'bg-white transition dark:bg-neutral-800/70 dark:hover:bg-neutral-800/80',
|
||||
themeGlassyBorder,
|
||||
)}>
|
||||
<div className="flex flex-1 flex-col gap-3 self-stretch">
|
||||
<div className="flex items-center gap-3">
|
||||
<div
|
||||
className={clsx(
|
||||
'size-10 flex items-center justify-center rounded',
|
||||
theme.gradient.className,
|
||||
)}>
|
||||
<theme.iconOutline className="size-6 text-white" />
|
||||
</div>
|
||||
<Anchor href={href} variant="unstyled">
|
||||
<span aria-hidden={true} className="absolute inset-0" />
|
||||
<Heading level="heading6">{name}</Heading>
|
||||
</Anchor>
|
||||
{isStarted && (
|
||||
<span>
|
||||
<Badge
|
||||
label={intl.formatMessage({
|
||||
defaultMessage: 'Started',
|
||||
description: 'Started on study plan label',
|
||||
id: 'cKn3cK',
|
||||
})}
|
||||
size="sm"
|
||||
variant="info"
|
||||
/>
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<Text className="grow" color="secondary" size="body2">
|
||||
{shortDescription}
|
||||
</Text>
|
||||
<div className="flex flex-wrap items-center gap-x-8 gap-y-2">
|
||||
<QuestionCountLabel count={questionCount} showIcon={true} />
|
||||
<QuestionDifficultySummary
|
||||
easy={difficultySummary.easy}
|
||||
hard={difficultySummary.hard}
|
||||
medium={difficultySummary.medium}
|
||||
showIcon={true}
|
||||
/>
|
||||
{isStarted && (
|
||||
<CompletionCountSummary
|
||||
completed={completionCount}
|
||||
total={questionCount}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<RiArrowRightLine className="group-hover:text-brand-dark dark:group-hover:text-brand size-6 text-neutral-400 transition-colors" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export type FocusAreaDifficultySummary = Record<
|
||||
FocusAreaType,
|
||||
Record<QuestionDifficulty, number>
|
||||
>;
|
||||
|
||||
type Props = Readonly<{
|
||||
difficultySummary: FocusAreaDifficultySummary;
|
||||
focusAreas: FocusAreas;
|
||||
}>;
|
||||
|
||||
export default function InterviewsFocusAreaListPage({
|
||||
focusAreas,
|
||||
difficultySummary,
|
||||
}: Props) {
|
||||
const intl = useIntl();
|
||||
const user = useUser();
|
||||
const { data: questionListSessions } =
|
||||
trpc.questionLists.getActiveSessions.useQuery(undefined, {
|
||||
enabled: !!user,
|
||||
});
|
||||
|
||||
const sessions = questionListSessions ?? [];
|
||||
const areas = Object.values(focusAreas);
|
||||
|
||||
return (
|
||||
<Container
|
||||
className={clsx(
|
||||
'flex flex-col',
|
||||
'py-4 md:py-6 lg:py-8 xl:py-16',
|
||||
'gap-y-8 md:gap-y-10 2xl:gap-y-12',
|
||||
)}>
|
||||
<div className="flex flex-col gap-3">
|
||||
<Heading level="heading5">
|
||||
{intl.formatMessage({
|
||||
defaultMessage: 'Focus areas',
|
||||
description: 'Title of focus areas page',
|
||||
id: 'Zui1cu',
|
||||
})}
|
||||
</Heading>
|
||||
<Text className="block" color="secondary" size="body2">
|
||||
{intl.formatMessage({
|
||||
defaultMessage:
|
||||
'Discover focus areas tailored to your needs to help you prepare for your upcoming technical interviews.',
|
||||
description: 'Description for focus areas page',
|
||||
id: 'Qe4ww/',
|
||||
})}
|
||||
</Text>
|
||||
</div>
|
||||
<Section>
|
||||
<div className="grid gap-4 lg:grid-cols-2">
|
||||
{areas.map((area) => {
|
||||
const session = sessions.find(
|
||||
(session_) => session_.key === area.type,
|
||||
);
|
||||
const completionCount = session?._count.progress;
|
||||
|
||||
return (
|
||||
<FocusAreaCard
|
||||
key={area.type}
|
||||
area={area}
|
||||
completionCount={completionCount}
|
||||
difficultySummary={difficultySummary[area.type]}
|
||||
isStarted={session != null}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</Section>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,119 +0,0 @@
|
|||
import type { Metadata } from 'next/types';
|
||||
import { CourseJsonLd } from 'next-seo';
|
||||
import type { IntlShape } from 'react-intl';
|
||||
|
||||
import type { FocusAreaType } from '~/data/focus-areas/FocusAreas';
|
||||
import { getFocusAreas } from '~/data/focus-areas/FocusAreas';
|
||||
|
||||
import type { QuestionMetadata } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import { sortQuestions } from '~/components/interviews/questions/listings/filters/QuestionsProcessor';
|
||||
|
||||
import { fetchInterviewListingBottomContent } from '~/db/contentlayer/InterviewsListingBottomContentReader';
|
||||
import { fetchQuestionsBySlug } from '~/db/QuestionsListReader';
|
||||
import { getIntlServerOnly } from '~/i18n';
|
||||
import { generateStaticParamsWithLocale } from '~/next-i18nostic/src';
|
||||
import defaultMetadata from '~/seo/defaultMetadata';
|
||||
import { getSiteOrigin } from '~/seo/siteUrl';
|
||||
|
||||
import InterviewsFocusAreaPage from './InterviewsFocusAreaPage';
|
||||
import { INTERVIEWS_REVAMP_BOTTOM_CONTENT } from '../../../../../../../../data/FeatureFlags';
|
||||
|
||||
async function getFocusAreaSEO(focusAreaType: FocusAreaType, locale: string) {
|
||||
const intl = await getIntlServerOnly(locale);
|
||||
// TODO: Remove this IntlShape typecast.
|
||||
const focusAreas = getFocusAreas(intl as IntlShape);
|
||||
const focusArea = focusAreas[focusAreaType];
|
||||
|
||||
return { ...focusArea.seo, href: focusArea.href };
|
||||
}
|
||||
|
||||
export async function generateStaticParams() {
|
||||
const focusAreas: Record<FocusAreaType, null> = {
|
||||
accessibility: null,
|
||||
'async-operations': null,
|
||||
'data-structures-algorithms': null,
|
||||
'design-system-components': null,
|
||||
'dom-manipulation': null,
|
||||
forms: null,
|
||||
'javascript-polyfills': null,
|
||||
lodash: null,
|
||||
'state-management': null,
|
||||
};
|
||||
|
||||
return generateStaticParamsWithLocale(
|
||||
Object.keys(focusAreas).map((focusArea) => ({ focusArea })),
|
||||
);
|
||||
}
|
||||
|
||||
type Props = Readonly<{
|
||||
params: {
|
||||
focusArea: FocusAreaType;
|
||||
locale: string;
|
||||
};
|
||||
}>;
|
||||
|
||||
export async function generateMetadata({ params }: Props): Promise<Metadata> {
|
||||
const { locale, focusArea: focusAreaType } = params;
|
||||
|
||||
const { title, description, href, socialTitle } = await getFocusAreaSEO(
|
||||
focusAreaType,
|
||||
locale,
|
||||
);
|
||||
|
||||
return defaultMetadata({
|
||||
description,
|
||||
locale,
|
||||
pathname: href,
|
||||
socialTitle,
|
||||
title,
|
||||
});
|
||||
}
|
||||
|
||||
export default async function Page({ params }: Props) {
|
||||
const { locale, focusArea: focusAreaType } = params;
|
||||
|
||||
const intl = await getIntlServerOnly(locale);
|
||||
|
||||
// TODO: Remove this IntlShape typecast.
|
||||
const focusAreas = getFocusAreas(intl as IntlShape);
|
||||
const focusArea = focusAreas[focusAreaType];
|
||||
const [{ title, description }, questions, bottomContent] = await Promise.all([
|
||||
getFocusAreaSEO(focusAreaType, locale),
|
||||
fetchQuestionsBySlug(focusArea.questions, locale),
|
||||
fetchInterviewListingBottomContent(`${focusAreaType}-focus-area`),
|
||||
]);
|
||||
const codingQuestionsForPlan = [
|
||||
...questions.javascript,
|
||||
...questions['user-interface'],
|
||||
...questions.algo,
|
||||
];
|
||||
const systemDesignQuestionsForPlan = questions['system-design'];
|
||||
const quizQuestionsForPlan = questions.quiz;
|
||||
|
||||
return (
|
||||
<>
|
||||
<CourseJsonLd
|
||||
courseName={title}
|
||||
description={description}
|
||||
provider={{
|
||||
name: 'GreatFrontEnd',
|
||||
url: getSiteOrigin(),
|
||||
}}
|
||||
useAppDir={true}
|
||||
/>
|
||||
<InterviewsFocusAreaPage
|
||||
bottomContent={
|
||||
INTERVIEWS_REVAMP_BOTTOM_CONTENT ? bottomContent : undefined
|
||||
}
|
||||
codingQuestions={codingQuestionsForPlan}
|
||||
focusArea={focusArea}
|
||||
quizQuestions={sortQuestions(
|
||||
quizQuestionsForPlan as ReadonlyArray<QuestionMetadata>,
|
||||
'importance',
|
||||
false,
|
||||
)}
|
||||
systemDesignQuestions={systemDesignQuestionsForPlan}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,146 +0,0 @@
|
|||
import type { Metadata } from 'next/types';
|
||||
import type { IntlShape } from 'react-intl';
|
||||
|
||||
import { INTERVIEWS_REVAMP_2024 } from '~/data/FeatureFlags';
|
||||
import { getFocusAreas } from '~/data/focus-areas/FocusAreas';
|
||||
|
||||
import type {
|
||||
QuestionDifficulty,
|
||||
QuestionList_DEPRECATED,
|
||||
} from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import { countQuestionsByDifficulty } from '~/components/interviews/questions/listings/filters/QuestionsProcessor';
|
||||
|
||||
import { fetchInterviewListingBottomContent } from '~/db/contentlayer/InterviewsListingBottomContentReader';
|
||||
import { fetchQuestionsBySlug } from '~/db/QuestionsListReader';
|
||||
import { getIntlServerOnly } from '~/i18n';
|
||||
import defaultMetadata from '~/seo/defaultMetadata';
|
||||
|
||||
import InterviewsFocusAreaListPage from './InterviewsFocusAreaListPage';
|
||||
import InterviewsRevampFocusAreaListPage from './InterviewsRevampFocusAreaListPage';
|
||||
|
||||
export const dynamic = 'force-static';
|
||||
|
||||
type Props = Readonly<{
|
||||
params: Readonly<{
|
||||
locale: string;
|
||||
}>;
|
||||
}>;
|
||||
|
||||
async function getPageSEOMetadata({ params }: Props) {
|
||||
const { locale } = params;
|
||||
const intl = await getIntlServerOnly(locale);
|
||||
const focusAreas = getFocusAreas(intl as IntlShape);
|
||||
|
||||
return {
|
||||
description: intl.formatMessage(
|
||||
{
|
||||
defaultMessage:
|
||||
'Explore {topicsCount} critical topics for front end interviews. Master them with targeted practice questions—each with detailed solutions and tests to learn from.',
|
||||
description: 'Page description for focus areas listing',
|
||||
id: 'UISwUX',
|
||||
},
|
||||
{
|
||||
topicsCount: Object.keys(focusAreas).length,
|
||||
},
|
||||
),
|
||||
href: '/focus-areas',
|
||||
socialTitle: intl.formatMessage({
|
||||
defaultMessage: 'Practice Questions by Focus Area | GreatFrontEnd',
|
||||
description: 'Social title for focus areas listing',
|
||||
id: 'DUKB3u',
|
||||
}),
|
||||
title: intl.formatMessage({
|
||||
defaultMessage:
|
||||
'Front End Interview Focus Areas—Accessibility, Forms and more',
|
||||
description: 'Page title for focus areas listing',
|
||||
id: 'UET3FT',
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
export async function generateMetadata({ params }: Props): Promise<Metadata> {
|
||||
const { locale } = params;
|
||||
|
||||
const { title, description, socialTitle, href } = await getPageSEOMetadata({
|
||||
params,
|
||||
});
|
||||
|
||||
return defaultMetadata({
|
||||
description,
|
||||
locale,
|
||||
pathname: href,
|
||||
socialTitle,
|
||||
title,
|
||||
});
|
||||
}
|
||||
|
||||
async function getDifficultySummaryForList(
|
||||
list: QuestionList_DEPRECATED,
|
||||
locale: string,
|
||||
): Promise<Record<QuestionDifficulty, number>> {
|
||||
const questions = await fetchQuestionsBySlug(list.questions, locale);
|
||||
|
||||
return countQuestionsByDifficulty([
|
||||
...questions.javascript,
|
||||
...questions['user-interface'],
|
||||
...questions['system-design'],
|
||||
]);
|
||||
}
|
||||
|
||||
export default async function Page({ params }: Props) {
|
||||
const { locale } = params;
|
||||
|
||||
const [intl] = await Promise.all([
|
||||
getIntlServerOnly(locale),
|
||||
getPageSEOMetadata({ params }),
|
||||
]);
|
||||
// TODO: Remove this IntlShape typecast.
|
||||
const focusAreas = getFocusAreas(intl as IntlShape);
|
||||
|
||||
const [
|
||||
difficultySummaryA11y,
|
||||
difficultySummaryAsync,
|
||||
difficultySummaryDSA,
|
||||
difficultySummaryDSC,
|
||||
difficultySummaryDOM,
|
||||
difficultySummaryForms,
|
||||
difficultySummaryLodash,
|
||||
difficultySummaryJavaScriptPolyfills,
|
||||
difficultySummaryStateManagement,
|
||||
] = await Promise.all(
|
||||
[
|
||||
focusAreas.accessibility,
|
||||
focusAreas['async-operations'],
|
||||
focusAreas['data-structures-algorithms'],
|
||||
focusAreas['design-system-components'],
|
||||
focusAreas['dom-manipulation'],
|
||||
focusAreas.forms,
|
||||
focusAreas.lodash,
|
||||
focusAreas['javascript-polyfills'],
|
||||
focusAreas['state-management'],
|
||||
].map((area) => getDifficultySummaryForList(area, locale)),
|
||||
);
|
||||
const bottomContent = await fetchInterviewListingBottomContent('focus-areas');
|
||||
|
||||
return INTERVIEWS_REVAMP_2024 ? (
|
||||
<InterviewsRevampFocusAreaListPage
|
||||
bottomContent={bottomContent}
|
||||
focusAreas={focusAreas}
|
||||
/>
|
||||
) : (
|
||||
<InterviewsFocusAreaListPage
|
||||
difficultySummary={{
|
||||
accessibility: difficultySummaryA11y,
|
||||
'async-operations': difficultySummaryAsync,
|
||||
'data-structures-algorithms': difficultySummaryDSA,
|
||||
'design-system-components': difficultySummaryDSC,
|
||||
'dom-manipulation': difficultySummaryDOM,
|
||||
forms: difficultySummaryForms,
|
||||
'javascript-polyfills': difficultySummaryJavaScriptPolyfills,
|
||||
lodash: difficultySummaryLodash,
|
||||
'state-management': difficultySummaryStateManagement,
|
||||
}}
|
||||
focusAreas={focusAreas}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,7 +1,10 @@
|
|||
'use client';
|
||||
|
||||
import clsx from 'clsx';
|
||||
import type { InterviewsListingBottomContent } from 'contentlayer/generated';
|
||||
import type {
|
||||
InterviewsListingBottomContent,
|
||||
InterviewsStudyList,
|
||||
} from 'contentlayer/generated';
|
||||
import {
|
||||
RiListCheck3,
|
||||
RiVerifiedBadgeLine,
|
||||
|
|
@ -11,13 +14,12 @@ import {
|
|||
import { trpc } from '~/hooks/trpc';
|
||||
|
||||
import {
|
||||
categorizeFocusAreas,
|
||||
type FocusAreas,
|
||||
getFocusAreaTheme,
|
||||
categorizeFocusAreas_DEPRECATED,
|
||||
getFocusAreaTheme_DEPRECATED,
|
||||
} from '~/data/focus-areas/FocusAreas';
|
||||
|
||||
import InterviewsListPageHeader from '~/components/interviews/common/InterviewsListPageHeader';
|
||||
import InterviewsLearningListCard from '~/components/interviews/questions/listings/learning/InterviewsLearningListCard';
|
||||
import InterviewsStudyListCard from '~/components/interviews/questions/listings/learning/InterviewsStudyListCard';
|
||||
import { useIntl } from '~/components/intl';
|
||||
import MDXContent from '~/components/mdx/MDXContent';
|
||||
import Container from '~/components/ui/Container';
|
||||
|
|
@ -30,7 +32,7 @@ import { useUser } from '@supabase/auth-helpers-react';
|
|||
|
||||
type Props = Readonly<{
|
||||
bottomContent?: InterviewsListingBottomContent;
|
||||
focusAreas: FocusAreas;
|
||||
focusAreas: ReadonlyArray<InterviewsStudyList>;
|
||||
}>;
|
||||
|
||||
export default function InterviewsRevampFocusAreaListPage({
|
||||
|
|
@ -45,7 +47,7 @@ export default function InterviewsRevampFocusAreaListPage({
|
|||
});
|
||||
|
||||
const sessions = questionListSessions ?? [];
|
||||
const focusAreasCategories = categorizeFocusAreas(intl);
|
||||
const focusAreasCategories = categorizeFocusAreas_DEPRECATED(intl);
|
||||
|
||||
const features = [
|
||||
{
|
||||
|
|
@ -124,10 +126,10 @@ export default function InterviewsRevampFocusAreaListPage({
|
|||
(session_) => session_.key === focusArea.type,
|
||||
);
|
||||
const completionCount = session?._count.progress;
|
||||
const theme = getFocusAreaTheme(focusArea.type);
|
||||
const theme = getFocusAreaTheme_DEPRECATED(focusArea.type);
|
||||
|
||||
return (
|
||||
<InterviewsLearningListCard
|
||||
<InterviewsStudyListCard
|
||||
key={focusArea.type}
|
||||
completionCount={completionCount}
|
||||
isStarted={session != null}
|
||||
|
|
@ -1,7 +1,10 @@
|
|||
'use client';
|
||||
|
||||
import clsx from 'clsx';
|
||||
import type { InterviewsListingBottomContent } from 'contentlayer/generated';
|
||||
import type {
|
||||
InterviewsListingBottomContent,
|
||||
InterviewsStudyList,
|
||||
} from 'contentlayer/generated';
|
||||
import {
|
||||
RiArrowLeftLine,
|
||||
RiQuestionnaireLine,
|
||||
|
|
@ -12,13 +15,16 @@ import {
|
|||
import { trpc } from '~/hooks/trpc';
|
||||
|
||||
import { INTERVIEWS_REVAMP_2024 } from '~/data/FeatureFlags';
|
||||
import type { FocusArea } from '~/data/focus-areas/FocusAreas';
|
||||
import { getFocusAreaTheme } from '~/data/focus-areas/FocusAreas';
|
||||
import { getFocusAreaTheme_DEPRECATED } from '~/data/focus-areas/FocusAreas';
|
||||
|
||||
import type { QuestionMetadata } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import QuestionsLearningList from '~/components/interviews/questions/listings/learning/QuestionsLearningList';
|
||||
import QuestionsLearningListPageTitleSection from '~/components/interviews/questions/listings/learning/QuestionsLearningListPageTitleSection';
|
||||
import QuestionsLearningListTitleSection from '~/components/interviews/questions/listings/learning/QuestionsLearningListTitleSection';
|
||||
import type {
|
||||
QuestionFormat,
|
||||
QuestionMetadata,
|
||||
QuestionSlug,
|
||||
} from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
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';
|
||||
|
|
@ -30,24 +36,23 @@ import {
|
|||
categorizeQuestionsProgress,
|
||||
countNumberOfQuestionsInList,
|
||||
filterQuestionsProgressByList,
|
||||
flattenQuestionFormatMetadata,
|
||||
} from '~/db/QuestionsUtils';
|
||||
|
||||
import { useUser } from '@supabase/auth-helpers-react';
|
||||
|
||||
type Props = Readonly<{
|
||||
bottomContent?: InterviewsListingBottomContent;
|
||||
codingQuestions: ReadonlyArray<QuestionMetadata>;
|
||||
focusArea: FocusArea;
|
||||
quizQuestions: ReadonlyArray<QuestionMetadata>;
|
||||
systemDesignQuestions: ReadonlyArray<QuestionMetadata>;
|
||||
focusArea: InterviewsStudyList;
|
||||
questionsMetadata: Record<QuestionFormat, ReadonlyArray<QuestionMetadata>>;
|
||||
questionsSlugs: Record<QuestionFormat, ReadonlyArray<QuestionSlug>>;
|
||||
}>;
|
||||
|
||||
export default function InterviewsFocusAreaPage({
|
||||
quizQuestions,
|
||||
codingQuestions,
|
||||
systemDesignQuestions,
|
||||
focusArea,
|
||||
bottomContent,
|
||||
focusArea,
|
||||
questionsMetadata,
|
||||
questionsSlugs,
|
||||
}: Props) {
|
||||
const intl = useIntl();
|
||||
const user = useUser();
|
||||
|
|
@ -63,10 +68,10 @@ export default function InterviewsFocusAreaPage({
|
|||
|
||||
const questionsOverallProgress = filterQuestionsProgressByList(
|
||||
questionsProgressAll,
|
||||
focusArea.questions,
|
||||
questionsSlugs,
|
||||
);
|
||||
const focusAreaTheme = getFocusAreaTheme(focusArea.type);
|
||||
const questionCount = countNumberOfQuestionsInList(focusArea.questions);
|
||||
const focusAreaTheme = getFocusAreaTheme_DEPRECATED(focusArea.slug);
|
||||
const questionCount = countNumberOfQuestionsInList(questionsSlugs);
|
||||
|
||||
const features = [
|
||||
{
|
||||
|
|
@ -124,11 +129,7 @@ export default function InterviewsFocusAreaPage({
|
|||
features={features}
|
||||
icon={focusAreaTheme.iconOutline}
|
||||
overallProgress={questionProgressParam ?? []}
|
||||
questions={[
|
||||
...quizQuestions,
|
||||
...codingQuestions,
|
||||
...systemDesignQuestions,
|
||||
]}
|
||||
questions={flattenQuestionFormatMetadata(questionsMetadata)}
|
||||
questionsSessionKey={focusArea.type}
|
||||
themeBackgroundClass={focusAreaTheme.gradient.className}
|
||||
title={focusArea.longName}
|
||||
|
|
@ -136,18 +137,14 @@ export default function InterviewsFocusAreaPage({
|
|||
<Divider />
|
||||
</>
|
||||
) : (
|
||||
<QuestionsLearningListTitleSection
|
||||
<QuestionsStudyListTitleSection_DEPRECATED
|
||||
description={focusArea.description}
|
||||
icon={focusAreaTheme.iconOutline}
|
||||
overallProgress={questionProgressParam ?? []}
|
||||
progressTrackingAvailableToNonPremiumUsers={true}
|
||||
questionCount={questionCount}
|
||||
questionListKey={focusArea.type}
|
||||
questions={[
|
||||
...codingQuestions,
|
||||
...quizQuestions,
|
||||
...systemDesignQuestions,
|
||||
]}
|
||||
questions={flattenQuestionFormatMetadata(questionsMetadata)}
|
||||
themeBackgroundClass={focusAreaTheme.gradient.className}
|
||||
title={focusArea.longName}
|
||||
/>
|
||||
|
|
@ -155,14 +152,17 @@ export default function InterviewsFocusAreaPage({
|
|||
</div>
|
||||
<Section>
|
||||
<QuestionsLearningList
|
||||
codingQuestions={codingQuestions}
|
||||
listKey={focusArea.type}
|
||||
codingQuestions={[
|
||||
...questionsMetadata.javascript,
|
||||
...questionsMetadata['user-interface'],
|
||||
...questionsMetadata.algo,
|
||||
]}
|
||||
listKey={focusArea.slug}
|
||||
overallProgress={questionsOverallProgress}
|
||||
quizQuestions={quizQuestions}
|
||||
systemDesignQuestions={systemDesignQuestions}
|
||||
quizQuestions={questionsMetadata.quiz}
|
||||
systemDesignQuestions={questionsMetadata['system-design']}
|
||||
/>
|
||||
</Section>
|
||||
|
||||
{bottomContent && (
|
||||
<>
|
||||
<Divider className="my-8" />
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
import { notFound } from 'next/navigation';
|
||||
import type { Metadata } from 'next/types';
|
||||
import { CourseJsonLd } from 'next-seo';
|
||||
|
||||
import { INTERVIEWS_REVAMP_BOTTOM_CONTENT } from '~/data/FeatureFlags';
|
||||
|
||||
import { sortQuestions } from '~/components/interviews/questions/listings/filters/QuestionsProcessor';
|
||||
|
||||
import { fetchInterviewListingBottomContent } from '~/db/contentlayer/InterviewsListingBottomContentReader';
|
||||
import {
|
||||
fetchInterviewsStudyList,
|
||||
fetchInterviewsStudyLists,
|
||||
} from '~/db/contentlayer/InterviewsStudyListReader';
|
||||
import { fetchQuestionsBySlug } from '~/db/QuestionsListReader';
|
||||
import { generateStaticParamsWithLocale } from '~/next-i18nostic/src';
|
||||
import defaultMetadata from '~/seo/defaultMetadata';
|
||||
import { getSiteOrigin } from '~/seo/siteUrl';
|
||||
|
||||
import InterviewsFocusAreaPage from './InterviewsFocusAreaPage';
|
||||
|
||||
type Props = Readonly<{
|
||||
params: {
|
||||
focusArea: string;
|
||||
locale: string;
|
||||
};
|
||||
}>;
|
||||
|
||||
async function getPageSEOMetadata({ focusArea }: Props['params']) {
|
||||
const focusAreaDocument = await fetchInterviewsStudyList(focusArea);
|
||||
|
||||
if (focusAreaDocument == null) {
|
||||
return notFound();
|
||||
}
|
||||
|
||||
return {
|
||||
description: focusAreaDocument.seoDescription,
|
||||
href: focusAreaDocument.href,
|
||||
socialTitle: focusAreaDocument.socialTitle,
|
||||
title: focusAreaDocument.seoTitle,
|
||||
};
|
||||
}
|
||||
|
||||
export async function generateStaticParams() {
|
||||
const focusAreas = await fetchInterviewsStudyLists('focus-area');
|
||||
|
||||
return generateStaticParamsWithLocale(
|
||||
focusAreas.map((focusArea) => ({ focusArea: focusArea.slug })),
|
||||
);
|
||||
}
|
||||
|
||||
export async function generateMetadata({ params }: Props): Promise<Metadata> {
|
||||
const { locale } = params;
|
||||
|
||||
const { title, description, href, socialTitle } =
|
||||
await getPageSEOMetadata(params);
|
||||
|
||||
return defaultMetadata({
|
||||
description,
|
||||
locale,
|
||||
pathname: href,
|
||||
socialTitle,
|
||||
title,
|
||||
});
|
||||
}
|
||||
|
||||
export default async function Page({ params }: Props) {
|
||||
const { locale, focusArea: focusAreaSlug } = params;
|
||||
|
||||
const focusArea = await fetchInterviewsStudyList(focusAreaSlug);
|
||||
|
||||
if (focusArea == null) {
|
||||
return notFound();
|
||||
}
|
||||
|
||||
const questionsSlugs = {
|
||||
algo: focusArea.questionsAlgo ?? [],
|
||||
javascript: focusArea.questionsJavaScript ?? [],
|
||||
quiz: focusArea.questionsQuiz ?? [],
|
||||
'system-design': focusArea.questionsSystemDesign ?? [],
|
||||
'user-interface': focusArea.questionsUserInterface ?? [],
|
||||
};
|
||||
|
||||
const [questionsMetadata, bottomContent] = await Promise.all([
|
||||
fetchQuestionsBySlug(questionsSlugs, locale),
|
||||
fetchInterviewListingBottomContent(`${focusAreaSlug}-focus-area`),
|
||||
]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<CourseJsonLd
|
||||
courseName={focusArea.seoTitle}
|
||||
description={focusArea.seoDescription}
|
||||
provider={{
|
||||
name: 'GreatFrontEnd',
|
||||
url: getSiteOrigin(),
|
||||
}}
|
||||
useAppDir={true}
|
||||
/>
|
||||
<InterviewsFocusAreaPage
|
||||
bottomContent={
|
||||
INTERVIEWS_REVAMP_BOTTOM_CONTENT ? bottomContent : undefined
|
||||
}
|
||||
focusArea={focusArea}
|
||||
questionsMetadata={{
|
||||
...questionsMetadata,
|
||||
quiz: sortQuestions(questionsMetadata.quiz, 'importance', false),
|
||||
}}
|
||||
questionsSlugs={questionsSlugs}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
import type { Metadata } from 'next/types';
|
||||
|
||||
import { fetchInterviewListingBottomContent } from '~/db/contentlayer/InterviewsListingBottomContentReader';
|
||||
import { fetchInterviewsStudyLists } from '~/db/contentlayer/InterviewsStudyListReader';
|
||||
import { getIntlServerOnly } from '~/i18n';
|
||||
import defaultMetadata from '~/seo/defaultMetadata';
|
||||
|
||||
import InterviewsFocusAreaListPage from './InterviewsFocusAreaListPage';
|
||||
|
||||
export const dynamic = 'force-static';
|
||||
|
||||
type Props = Readonly<{
|
||||
params: Readonly<{
|
||||
locale: string;
|
||||
}>;
|
||||
}>;
|
||||
|
||||
async function getPageSEOMetadata({ params }: Props) {
|
||||
const { locale } = params;
|
||||
const [intl, focusAreas] = await Promise.all([
|
||||
getIntlServerOnly(locale),
|
||||
fetchInterviewsStudyLists('focus-area'),
|
||||
]);
|
||||
|
||||
return {
|
||||
description: intl.formatMessage(
|
||||
{
|
||||
defaultMessage:
|
||||
'Explore {topicsCount} critical topics for front end interviews. Master them with targeted practice questions—each with detailed solutions and tests to learn from.',
|
||||
description: 'Page description for focus areas listing',
|
||||
id: 'UISwUX',
|
||||
},
|
||||
{
|
||||
topicsCount: focusAreas.length,
|
||||
},
|
||||
),
|
||||
href: '/focus-areas',
|
||||
socialTitle: intl.formatMessage({
|
||||
defaultMessage: 'Practice Questions by Focus Area | GreatFrontEnd',
|
||||
description: 'Social title for focus areas listing',
|
||||
id: 'DUKB3u',
|
||||
}),
|
||||
title: intl.formatMessage({
|
||||
defaultMessage:
|
||||
'Front End Interview Focus Areas — Accessibility, Forms and more',
|
||||
description: 'Page title for focus areas listing',
|
||||
id: 'j/2Zyj',
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
export async function generateMetadata({ params }: Props): Promise<Metadata> {
|
||||
const { locale } = params;
|
||||
|
||||
const { title, description, socialTitle, href } = await getPageSEOMetadata({
|
||||
params,
|
||||
});
|
||||
|
||||
return defaultMetadata({
|
||||
description,
|
||||
locale,
|
||||
pathname: href,
|
||||
socialTitle,
|
||||
title,
|
||||
});
|
||||
}
|
||||
|
||||
export default async function Page() {
|
||||
const [focusAreas, bottomContent] = await Promise.all([
|
||||
fetchInterviewsStudyLists('focus-area'),
|
||||
fetchInterviewListingBottomContent('focus-areas'),
|
||||
]);
|
||||
|
||||
return (
|
||||
<InterviewsFocusAreaListPage
|
||||
bottomContent={bottomContent}
|
||||
focusAreas={focusAreas}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
@ -10,7 +10,7 @@ import type { PreparationPlan } from '~/data/plans/PreparationPlans';
|
|||
import { getPreparationPlanTheme } from '~/data/plans/PreparationPlans';
|
||||
|
||||
import type { QuestionMetadata } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import QuestionsLearningList from '~/components/interviews/questions/listings/learning/QuestionsLearningList';
|
||||
import QuestionsLearningList from '~/components/interviews/questions/listings/learning/QuestionsStudyList';
|
||||
import InterviewsRecommendedPrepStrategyPageTitleSection from '~/components/interviews/recommended/InterviewsRecommendedPrepStrategyPageTitleSection';
|
||||
import { FormattedMessage, useIntl } from '~/components/intl';
|
||||
import MDXContent from '~/components/mdx/MDXContent';
|
||||
|
|
@ -7,13 +7,12 @@ import InterviewsCompanyGuidePage from '~/components/interviews/company/Intervie
|
|||
import type { QuestionMetadata } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import { sortQuestions } from '~/components/interviews/questions/listings/filters/QuestionsProcessor';
|
||||
|
||||
import { fetchInterviewsLearningList } from '~/db/contentlayer/InterviewsLearningListReader';
|
||||
import { fetchInterviewListingBottomContent } from '~/db/contentlayer/InterviewsListingBottomContentReader';
|
||||
import { fetchInterviewsStudyList } from '~/db/contentlayer/InterviewsStudyListReader';
|
||||
import { fetchQuestionsBySlug } from '~/db/QuestionsListReader';
|
||||
import { getIntlServerOnly } from '~/i18n';
|
||||
import defaultMetadata from '~/seo/defaultMetadata';
|
||||
|
||||
// TODO(companies)
|
||||
// TODO(interviews/companies)
|
||||
// export async function generateStaticParams() {
|
||||
// return [];
|
||||
// }
|
||||
|
|
@ -26,11 +25,8 @@ type Props = Readonly<{
|
|||
}>;
|
||||
|
||||
async function getPageSEOMetadata({ params }: Props) {
|
||||
const { locale, slug } = params;
|
||||
const [intl, companyGuide] = await Promise.all([
|
||||
getIntlServerOnly(locale),
|
||||
fetchInterviewsLearningList(slug),
|
||||
]);
|
||||
const { slug } = params;
|
||||
const companyGuide = await fetchInterviewsStudyList(slug);
|
||||
|
||||
if (companyGuide == null) {
|
||||
return notFound();
|
||||
|
|
@ -62,13 +58,13 @@ export async function generateMetadata({ params }: Props): Promise<Metadata> {
|
|||
export default async function Page({ params }: Props) {
|
||||
const { locale, slug } = params;
|
||||
|
||||
const companyGuide = await fetchInterviewsLearningList(slug);
|
||||
const companyGuide = await fetchInterviewsStudyList(slug);
|
||||
|
||||
if (companyGuide == null) {
|
||||
return notFound();
|
||||
}
|
||||
|
||||
const companyQuestions = {
|
||||
const companyGuideQuestions = {
|
||||
algo: companyGuide.questionsAlgo ?? [],
|
||||
javascript: companyGuide.questionsJavaScript ?? [],
|
||||
quiz: companyGuide.questionsQuiz ?? [],
|
||||
|
|
@ -77,7 +73,7 @@ export default async function Page({ params }: Props) {
|
|||
};
|
||||
|
||||
const [questions, bottomContent] = await Promise.all([
|
||||
fetchQuestionsBySlug(companyQuestions, locale),
|
||||
fetchQuestionsBySlug(companyGuideQuestions, locale),
|
||||
fetchInterviewListingBottomContent('company-detail'),
|
||||
]);
|
||||
const codingQuestions = [
|
||||
|
|
@ -95,7 +91,7 @@ export default async function Page({ params }: Props) {
|
|||
}
|
||||
codingQuestions={codingQuestions}
|
||||
companyGuide={companyGuide}
|
||||
companyQuestions={companyQuestions}
|
||||
companyQuestions={companyGuideQuestions}
|
||||
quizQuestions={sortQuestions(
|
||||
quizQuestions as ReadonlyArray<QuestionMetadata>,
|
||||
'importance',
|
||||
|
|
@ -4,8 +4,8 @@ import { INTERVIEWS_REVAMP_BOTTOM_CONTENT } from '~/data/FeatureFlags';
|
|||
|
||||
import InterviewsCompanyGuideListPage from '~/components/interviews/company/InterviewsCompanyGuideListPage';
|
||||
|
||||
import { fetchInterviewsLearningLists } from '~/db/contentlayer/InterviewsLearningListReader';
|
||||
import { fetchInterviewListingBottomContent } from '~/db/contentlayer/InterviewsListingBottomContentReader';
|
||||
import { fetchInterviewsStudyLists } from '~/db/contentlayer/InterviewsStudyListReader';
|
||||
import { getIntlServerOnly } from '~/i18n';
|
||||
import defaultMetadata from '~/seo/defaultMetadata';
|
||||
|
||||
|
|
@ -57,7 +57,7 @@ export async function generateMetadata({ params }: Props): Promise<Metadata> {
|
|||
|
||||
export default async function Page() {
|
||||
const [companyGuides, bottomContent] = await Promise.all([
|
||||
fetchInterviewsLearningLists('company'),
|
||||
fetchInterviewsStudyLists('company'),
|
||||
fetchInterviewListingBottomContent('company'),
|
||||
]);
|
||||
const sortedGuides = companyGuides
|
||||
|
|
@ -14,7 +14,7 @@ import { getPreparationPlanTheme } from '~/data/plans/PreparationPlans';
|
|||
import FeedbackDialog from '~/components/global/feedback/FeedbackDialog';
|
||||
import { useUserPreferences } from '~/components/global/UserPreferencesProvider';
|
||||
import type { QuestionMetadata } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import QuestionsLearningList from '~/components/interviews/questions/listings/learning/QuestionsLearningList';
|
||||
import QuestionsLearningList from '~/components/interviews/questions/listings/learning/QuestionsStudyList';
|
||||
import InterviewsRecommendedPrepStrategyPageTitleSection from '~/components/interviews/recommended/InterviewsRecommendedPrepStrategyPageTitleSection';
|
||||
import { FormattedMessage, useIntl } from '~/components/intl';
|
||||
import MDXContent from '~/components/mdx/MDXContent';
|
||||
|
|
@ -22,9 +22,9 @@ 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/QuestionsLearningList';
|
||||
import QuestionsLearningListPageTitleSection from '~/components/interviews/questions/listings/learning/QuestionsLearningListPageTitleSection';
|
||||
import QuestionsLearningListTitleSection from '~/components/interviews/questions/listings/learning/QuestionsLearningListTitleSection';
|
||||
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';
|
||||
|
|
@ -147,7 +147,7 @@ export default function InterviewsStudyPlanPage({
|
|||
<Divider />
|
||||
</>
|
||||
) : (
|
||||
<QuestionsLearningListTitleSection
|
||||
<QuestionsStudyListTitleSection_DEPRECATED
|
||||
description={plan.description}
|
||||
difficultySummary={difficultySummary}
|
||||
feature="study-plans"
|
||||
|
|
@ -2,6 +2,7 @@ import type { Metadata } from 'next/types';
|
|||
import { CourseJsonLd } from 'next-seo';
|
||||
import type { IntlShape } from 'react-intl';
|
||||
|
||||
import { INTERVIEWS_REVAMP_BOTTOM_CONTENT } from '~/data/FeatureFlags';
|
||||
import type { PreparationPlanType } from '~/data/plans/PreparationPlans';
|
||||
import { getPreparationPlan } from '~/data/plans/PreparationPlans';
|
||||
|
||||
|
|
@ -20,7 +21,6 @@ import defaultMetadata from '~/seo/defaultMetadata';
|
|||
import { getSiteOrigin } from '~/seo/siteUrl';
|
||||
|
||||
import InterviewsStudyPlanPage from './InterviewsStudyPlanPage';
|
||||
import { INTERVIEWS_REVAMP_BOTTOM_CONTENT } from '../../../../../../../../data/FeatureFlags';
|
||||
|
||||
async function getPreparationPlansSEO(
|
||||
planType: PreparationPlanType,
|
||||
|
|
@ -13,7 +13,7 @@ import {
|
|||
} from '~/data/plans/PreparationPlans';
|
||||
|
||||
import InterviewsListPageHeader from '~/components/interviews/common/InterviewsListPageHeader';
|
||||
import InterviewsLearningListCard from '~/components/interviews/questions/listings/learning/InterviewsLearningListCard';
|
||||
import InterviewsStudyListCard from '~/components/interviews/questions/listings/learning/InterviewsStudyListCard';
|
||||
import InterviewsStudyPlanTestimonialsSection from '~/components/interviews/questions/listings/learning/study-plan/InterviewsStudyPlanTestimonialsSection';
|
||||
import { useIntl } from '~/components/intl';
|
||||
import MDXContent from '~/components/mdx/MDXContent';
|
||||
|
|
@ -118,7 +118,7 @@ export default function InterviewsRevampStudyPlansPage({
|
|||
const theme = getPreparationPlanTheme(studyPlan.type);
|
||||
|
||||
return (
|
||||
<InterviewsLearningListCard
|
||||
<InterviewsStudyListCard
|
||||
key={studyPlan.type}
|
||||
completionCount={completionCount}
|
||||
isStarted={session != null}
|
||||
|
|
@ -9,8 +9,8 @@ import {
|
|||
|
||||
import InterviewsDashboardPage from '~/components/interviews/revamp-dashboard/InterviewsDashboardPage';
|
||||
|
||||
import { fetchInterviewsLearningLists } from '~/db/contentlayer/InterviewsLearningListReader';
|
||||
import { fetchInterviewListingBottomContent } from '~/db/contentlayer/InterviewsListingBottomContentReader';
|
||||
import { fetchInterviewsStudyLists } from '~/db/contentlayer/InterviewsStudyListReader';
|
||||
import { fetchPreparationPlans } from '~/db/PreparationPlansReader';
|
||||
import {
|
||||
fetchQuestionsListCoding,
|
||||
|
|
@ -65,7 +65,7 @@ export default async function Page({ params }: Props) {
|
|||
fetchQuestionsListCoding(locale),
|
||||
fetchQuestionsListSystemDesign(locale),
|
||||
fetchInterviewListingBottomContent('dashboard'),
|
||||
fetchInterviewsLearningLists('company'),
|
||||
fetchInterviewsStudyLists('company'),
|
||||
]);
|
||||
const { framework, language } = categorizeQuestionsByFrameworkAndLanguage({
|
||||
codingQuestions,
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ export default async function Page({ params }: Props) {
|
|||
const isQuestionLockedForUser =
|
||||
question.metadata.premium && !canViewPremiumContent;
|
||||
|
||||
// TODO(interviews/playlist): fetch playlist questions instead.
|
||||
// TODO(interviews/learning-list): fetch list questions instead.
|
||||
const { questions: codingQuestions } = await fetchQuestionsListCoding(locale);
|
||||
const nextQuestions = sortQuestionsMultiple(
|
||||
codingQuestions.filter((questionItem) =>
|
||||
|
|
@ -80,7 +80,7 @@ export default async function Page({ params }: Props) {
|
|||
const isQuestionLockedForUser =
|
||||
question.metadata.premium && !canViewPremiumContent;
|
||||
|
||||
// TODO(interviews/playlist): fetch playlist questions instead.
|
||||
// TODO(interviews/learning-list): fetch list questions instead.
|
||||
const { questions: codingQuestions } = await fetchQuestionsListCoding(locale);
|
||||
const nextQuestions = sortQuestionsMultiple(
|
||||
codingQuestions.filter((questionItem) =>
|
||||
|
|
@ -171,7 +171,7 @@ export default async function Page({ params }: Props) {
|
|||
question.metadata.premium && !canViewPremiumContent;
|
||||
const { url } = frameworkAgnosticLinks(question, mode);
|
||||
|
||||
// TODO(interviews/playlist): fetch playlist questions instead.
|
||||
// TODO(interviews/learning-list): fetch list questions instead.
|
||||
const { questions: codingQuestions } = await fetchQuestionsListCoding(locale);
|
||||
const nextQuestions = sortQuestionsMultiple(
|
||||
codingQuestions.filter((questionItem) =>
|
||||
|
|
@ -21,7 +21,7 @@ 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 QuestionsLearningListTitleSection from '~/components/interviews/questions/listings/learning/QuestionsLearningListTitleSection';
|
||||
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';
|
||||
|
|
@ -372,7 +372,7 @@ export default function ScrapbookPage() {
|
|||
<Section>
|
||||
<div>
|
||||
<UIExamplesGroup>
|
||||
<QuestionsLearningListTitleSection
|
||||
<QuestionsStudyListTitleSection_DEPRECATED
|
||||
difficultySummary={{
|
||||
easy: 30,
|
||||
hard: 10,
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ const GuidesContext = createContext<GuidesContextType>({
|
|||
export function useGuidesContext() {
|
||||
const context = useContext(GuidesContext);
|
||||
|
||||
// TODO(interviews/playlist): define GuideContext for playlist mode.
|
||||
// TODO(interviews/learning-list): define GuideContext for learning-list mode.
|
||||
// if (context === undefined) {
|
||||
// throw new Error(
|
||||
// 'useGuidesContext must be used within a GuidesContextProvider',
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import clsx from 'clsx';
|
||||
import type { InterviewsLearningList } from 'contentlayer/generated';
|
||||
import type { InterviewsStudyList } from 'contentlayer/generated';
|
||||
import { RiArrowRightLine } from 'react-icons/ri';
|
||||
|
||||
import { INTERVIEWS_REVAMP_2024 } from '~/data/FeatureFlags';
|
||||
|
|
@ -21,7 +21,7 @@ import CompletionCountSummary from '../questions/listings/stats/CompletionCountS
|
|||
import QuestionCountLabel from '../questions/metadata/QuestionCountLabel';
|
||||
|
||||
type Props = Readonly<{
|
||||
companyGuide: InterviewsLearningList;
|
||||
companyGuide: InterviewsStudyList;
|
||||
completionCount?: number;
|
||||
isStarted?: boolean;
|
||||
showProgressBar?: boolean;
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
import clsx from 'clsx';
|
||||
import type {
|
||||
InterviewsLearningList,
|
||||
InterviewsListingBottomContent,
|
||||
InterviewsStudyList,
|
||||
} from 'contentlayer/generated';
|
||||
import {
|
||||
RiThumbUpLine,
|
||||
|
|
@ -26,10 +26,10 @@ import InterviewsCompanyGuideListWithFilters from './InterviewsCompanyGuideListW
|
|||
|
||||
type Props = Readonly<{
|
||||
bottomContent?: InterviewsListingBottomContent;
|
||||
companyGuides: Array<InterviewsLearningList>;
|
||||
companyGuides: Array<InterviewsStudyList>;
|
||||
}>;
|
||||
|
||||
export default function InterviewsLearningListListPage({
|
||||
export default function InterviewsStudyListListPage({
|
||||
companyGuides,
|
||||
bottomContent,
|
||||
}: Props) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import clsx from 'clsx';
|
||||
import type { InterviewsLearningList } from 'contentlayer/generated';
|
||||
import type { InterviewsStudyList } from 'contentlayer/generated';
|
||||
import { useState } from 'react';
|
||||
import { RiSearchLine } from 'react-icons/ri';
|
||||
|
||||
|
|
@ -21,10 +21,10 @@ import { InterviewsCompanyGuideCard } from './InterviewsCompanyGuideCard';
|
|||
import { useUser } from '@supabase/auth-helpers-react';
|
||||
|
||||
type Props = Readonly<{
|
||||
companyGuides: Array<InterviewsLearningList>;
|
||||
companyGuides: Array<InterviewsStudyList>;
|
||||
}>;
|
||||
|
||||
export default function InterviewsLearningListListWithFilters({
|
||||
export default function InterviewsStudyListListWithFilters({
|
||||
companyGuides,
|
||||
}: Props) {
|
||||
const intl = useIntl();
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
import clsx from 'clsx';
|
||||
import type {
|
||||
InterviewsLearningList,
|
||||
InterviewsListingBottomContent,
|
||||
InterviewsStudyList,
|
||||
} from 'contentlayer/generated';
|
||||
import { useMemo } from 'react';
|
||||
import {
|
||||
|
|
@ -27,9 +27,9 @@ import type {
|
|||
QuestionTopic,
|
||||
} from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import QuestionsList from '~/components/interviews/questions/listings/items/QuestionsList';
|
||||
import QuestionsLearningList from '~/components/interviews/questions/listings/learning/QuestionsLearningList';
|
||||
import QuestionsLearningListPageTitleSection from '~/components/interviews/questions/listings/learning/QuestionsLearningListPageTitleSection';
|
||||
import QuestionsLearningListTitleSection from '~/components/interviews/questions/listings/learning/QuestionsLearningListTitleSection';
|
||||
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';
|
||||
|
|
@ -53,7 +53,7 @@ import { useUser } from '@supabase/auth-helpers-react';
|
|||
type Props = Readonly<{
|
||||
bottomContent?: InterviewsListingBottomContent;
|
||||
codingQuestions: ReadonlyArray<QuestionMetadata>;
|
||||
companyGuide: InterviewsLearningList;
|
||||
companyGuide: InterviewsStudyList;
|
||||
companyQuestions: Record<QuestionFormat, ReadonlyArray<QuestionSlug>>;
|
||||
quizQuestions: ReadonlyArray<QuestionMetadata>;
|
||||
systemDesignQuestions: ReadonlyArray<QuestionMetadata>;
|
||||
|
|
@ -200,7 +200,7 @@ export default function InterviewsCompanyGuidePage({
|
|||
)}
|
||||
</>
|
||||
) : (
|
||||
<QuestionsLearningListTitleSection
|
||||
<QuestionsStudyListTitleSection_DEPRECATED
|
||||
description={<MDXContent mdxCode={companyGuide.body.code} />}
|
||||
feature="company-guides"
|
||||
icon={({ className, ...props }) => (
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import {
|
||||
getQuestionListThemes,
|
||||
useQuestionLists,
|
||||
useQuestionLists_DEPRECATED,
|
||||
} from '~/data/question-lists/QuestionListsHooks';
|
||||
|
||||
import InterviewsDashboardContinueLearning from '~/components/interviews/dashboard/InterviewsDashboardContinueLearning';
|
||||
|
|
@ -17,7 +17,7 @@ type Props = Readonly<{
|
|||
export default function InterviewsDashboardContinueLearningContainer({
|
||||
items,
|
||||
}: Props) {
|
||||
const questionLists = useQuestionLists();
|
||||
const questionLists = useQuestionLists_DEPRECATED();
|
||||
const themes = getQuestionListThemes();
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { useFocusAreas } from '~/data/focus-areas/FocusAreasHooks';
|
||||
import { useFocusAreas_DEPRECATED } from '~/data/focus-areas/FocusAreasHooks';
|
||||
|
||||
import { useIntl } from '~/components/intl';
|
||||
|
||||
|
|
@ -12,7 +12,7 @@ export default function InterviewsDashboardFeaturedFocusAreas({
|
|||
limit = Infinity,
|
||||
}: Props) {
|
||||
const intl = useIntl();
|
||||
const focusAreas = useFocusAreas();
|
||||
const focusAreas = useFocusAreas_DEPRECATED();
|
||||
const areas = [
|
||||
focusAreas['async-operations'],
|
||||
focusAreas['data-structures-algorithms'],
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import clsx from 'clsx';
|
||||
import { RiArrowRightLine, RiQuestionFill } from 'react-icons/ri';
|
||||
|
||||
import type { FocusArea } from '~/data/focus-areas/FocusAreas';
|
||||
import { getFocusAreaTheme } from '~/data/focus-areas/FocusAreas';
|
||||
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';
|
||||
|
|
@ -25,7 +25,7 @@ import QuestionCountLabel from '../questions/metadata/QuestionCountLabel';
|
|||
|
||||
type Props = Readonly<{
|
||||
description: string;
|
||||
focusAreas: ReadonlyArray<FocusArea>;
|
||||
focusAreas: ReadonlyArray<FocusArea_DEPRECATED>;
|
||||
title: string;
|
||||
}>;
|
||||
|
||||
|
|
@ -65,7 +65,7 @@ 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(type).iconSolid;
|
||||
const Icon = getFocusAreaTheme_DEPRECATED(type).iconSolid;
|
||||
|
||||
return (
|
||||
<Anchor key={type} href={href} variant="unstyled">
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import clsx from 'clsx';
|
||||
import type { InterviewsLearningList } from 'contentlayer/generated';
|
||||
import type { InterviewsStudyList } from 'contentlayer/generated';
|
||||
import { RiArrowRightLine } from 'react-icons/ri';
|
||||
import { useMediaQuery } from 'usehooks-ts';
|
||||
|
||||
|
|
@ -13,7 +13,7 @@ import Text from '~/components/ui/Text';
|
|||
import { themeGradientHeading } from '~/components/ui/theme';
|
||||
|
||||
type Props = Readonly<{
|
||||
companyGuides: ReadonlyArray<InterviewsLearningList>;
|
||||
companyGuides: ReadonlyArray<InterviewsStudyList>;
|
||||
}>;
|
||||
|
||||
export default function InterviewsMarketingCompaniesSection({
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ export type QuestionQuiz = QuestionBase;
|
|||
/**
|
||||
* @deprecated
|
||||
*
|
||||
* Use InterviewsLearningListDocument instead.
|
||||
* Use InterviewsStudyListDocument instead.
|
||||
*/
|
||||
export type QuestionList_DEPRECATED = Readonly<{
|
||||
description: string;
|
||||
|
|
@ -187,7 +187,7 @@ export type QuestionList_DEPRECATED = Readonly<{
|
|||
shortDescription: string;
|
||||
}>;
|
||||
|
||||
export type QuestionListTheme = Readonly<{
|
||||
export type QuestionListTheme_DEPRECATED = Readonly<{
|
||||
customIcon?: (props: { size?: 'lg' | 'md' | 'sm' }) => JSX.Element;
|
||||
gradient: ThemeGradient;
|
||||
iconOutline: (props: React.ComponentProps<'svg'>) => JSX.Element;
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ export function questionHrefWithList(
|
|||
urlObject.searchParams.append('list', listKey);
|
||||
|
||||
return (
|
||||
`/interviews/l/${listKey}` +
|
||||
`/interviews/study/${listKey}` +
|
||||
urlObject.pathname +
|
||||
urlObject.search +
|
||||
urlObject.hash
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import type { PreparationPlanSchedule } from '~/data/plans/PreparationPlans';
|
|||
import InterviewsEntityProgress from '~/components/interviews/common/InterviewsEntityProgress';
|
||||
import type {
|
||||
QuestionList_DEPRECATED,
|
||||
QuestionListTheme,
|
||||
QuestionListTheme_DEPRECATED,
|
||||
} from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import QuestionStudyAllocationLabel from '~/components/interviews/questions/metadata/QuestionStudyAllocationLabel';
|
||||
import { useIntl } from '~/components/intl';
|
||||
|
|
@ -30,10 +30,10 @@ type Props = Readonly<{
|
|||
isStarted?: boolean;
|
||||
metadata: QuestionList_DEPRECATED;
|
||||
schedule?: PreparationPlanSchedule;
|
||||
theme: QuestionListTheme;
|
||||
theme: QuestionListTheme_DEPRECATED;
|
||||
}>;
|
||||
|
||||
export default function InterviewsLearningListCard({
|
||||
export default function InterviewsStudyListCard({
|
||||
completionCount = 0,
|
||||
metadata,
|
||||
schedule,
|
||||
|
|
@ -9,7 +9,7 @@ function parseSlug(sourceFilePath: string) {
|
|||
return sourceFilePath.split(path.posix.sep)[3].replace(/\.mdx$/, '');
|
||||
}
|
||||
|
||||
export const InterviewsLearningListDocument = defineDocumentType(() => ({
|
||||
export const InterviewsStudyListDocument = defineDocumentType(() => ({
|
||||
computedFields: {
|
||||
category: {
|
||||
description: 'Type of list: study plan / focus area / company',
|
||||
|
|
@ -18,7 +18,7 @@ export const InterviewsLearningListDocument = defineDocumentType(() => ({
|
|||
type: 'enum',
|
||||
},
|
||||
href: {
|
||||
description: 'Link to learning list page',
|
||||
description: 'Link to study list page',
|
||||
resolve: (doc) => {
|
||||
const category = parseCategory(doc._raw.sourceFilePath);
|
||||
|
||||
|
|
@ -28,6 +28,9 @@ export const InterviewsLearningListDocument = defineDocumentType(() => ({
|
|||
doc._raw.sourceFilePath,
|
||||
)}/questions-guides`;
|
||||
}
|
||||
case 'focus-area': {
|
||||
return `/focus-area/${parseSlug(doc._raw.sourceFilePath)}`;
|
||||
}
|
||||
}
|
||||
},
|
||||
type: 'string',
|
||||
|
|
@ -112,6 +115,6 @@ export const InterviewsLearningListDocument = defineDocumentType(() => ({
|
|||
type: 'string',
|
||||
},
|
||||
},
|
||||
filePathPattern: 'interviews/learning-list/**/*.mdx',
|
||||
name: 'InterviewsLearningList',
|
||||
filePathPattern: 'interviews/study-list/**/*.mdx',
|
||||
name: 'InterviewsStudyList',
|
||||
}));
|
||||
|
|
@ -34,7 +34,10 @@ type Props = Readonly<{
|
|||
title: string;
|
||||
}>;
|
||||
|
||||
export default function QuestionsLearningListTitleSection({
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
export default function QuestionsStudyListTitleSection_DEPRECATED({
|
||||
description,
|
||||
difficultySummary,
|
||||
icon: Icon,
|
||||
|
|
@ -29,7 +29,7 @@ import type { QuestionProgress } from '~/db/QuestionsProgressTypes';
|
|||
|
||||
import InterviewsPageHeaderActions from '../common/InterviewsPageHeaderActions';
|
||||
import type { QuestionMetadata } from '../questions/common/QuestionsTypes';
|
||||
import QuestionsLearningListPageTitleSection from '../questions/listings/learning/QuestionsLearningListPageTitleSection';
|
||||
import QuestionsLearningListPageTitleSection from '../questions/listings/learning/QuestionsStudyListPageTitleSection';
|
||||
import QuestionListingQuestionCount from '../questions/listings/stats/QuestionListingQuestionCount';
|
||||
|
||||
import { useUser } from '@supabase/auth-helpers-react';
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import clsx from 'clsx';
|
|||
|
||||
import {
|
||||
getQuestionListThemes,
|
||||
useQuestionLists,
|
||||
useQuestionLists_DEPRECATED,
|
||||
} from '~/data/question-lists/QuestionListsHooks';
|
||||
|
||||
import getProgressBarGradient from '~/components/interviews/common/utils';
|
||||
|
|
@ -35,7 +35,7 @@ export default function InterviewsDashboardContinueLearningSection({
|
|||
questionListSessions,
|
||||
}: Props) {
|
||||
const intl = useIntl();
|
||||
const questionLists = useQuestionLists();
|
||||
const questionLists = useQuestionLists_DEPRECATED();
|
||||
const themes = getQuestionListThemes();
|
||||
|
||||
const items = questionListSessions
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import clsx from 'clsx';
|
||||
import type { InterviewsLearningList } from 'contentlayer/generated';
|
||||
import type { InterviewsStudyList } from 'contentlayer/generated';
|
||||
|
||||
import type { PreparationPlans } from '~/data/plans/PreparationPlans';
|
||||
|
||||
|
|
@ -25,7 +25,7 @@ import InterviewsDashboardPracticeQuestionsSection from './practice/InterviewsDa
|
|||
import type { LearningSession } from '@prisma/client';
|
||||
|
||||
type Props = Readonly<{
|
||||
companyGuides: Array<InterviewsLearningList>;
|
||||
companyGuides: Array<InterviewsStudyList>;
|
||||
guidesProgress: ReadonlyArray<
|
||||
Readonly<{ id: string; slug: string; type: GuideCategory }>
|
||||
>;
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
import clsx from 'clsx';
|
||||
import type {
|
||||
InterviewsLearningList,
|
||||
InterviewsListingBottomContent,
|
||||
InterviewsStudyList,
|
||||
} from 'contentlayer/generated';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
|
|
@ -33,7 +33,7 @@ import { useUser } from '@supabase/auth-helpers-react';
|
|||
|
||||
type Props = Readonly<{
|
||||
bottomContent?: InterviewsListingBottomContent;
|
||||
companyGuides: Array<InterviewsLearningList>;
|
||||
companyGuides: Array<InterviewsStudyList>;
|
||||
preparationPlans: PreparationPlans;
|
||||
questions: {
|
||||
codingQuestions: ReadonlyArray<QuestionMetadata>;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import type { InterviewsLearningList } from 'contentlayer/generated';
|
||||
import type { InterviewsStudyList } from 'contentlayer/generated';
|
||||
|
||||
import { useIntl } from '~/components/intl';
|
||||
|
||||
|
|
@ -8,7 +8,7 @@ import { InterviewsCompanyGuideCard } from '../company/InterviewsCompanyGuideCar
|
|||
import type { LearningSession } from '@prisma/client';
|
||||
|
||||
type Props = Readonly<{
|
||||
companyGuides: Array<InterviewsLearningList>;
|
||||
companyGuides: Array<InterviewsStudyList>;
|
||||
questionListSessions: Array<
|
||||
LearningSession & { _count: { progress: number } }
|
||||
>;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import {
|
|||
type PreparationPlans,
|
||||
} from '~/data/plans/PreparationPlans';
|
||||
|
||||
import InterviewsLearningListCard from '~/components/interviews/questions/listings/learning/InterviewsLearningListCard';
|
||||
import InterviewsStudyListCard from '~/components/interviews/questions/listings/learning/InterviewsStudyListCard';
|
||||
import { useIntl } from '~/components/intl';
|
||||
|
||||
import InterviewsDashboardLearningSection from './InterviewsDashboardLearningSection';
|
||||
|
|
@ -48,7 +48,7 @@ export default function InterviewsDashboardStudyPlansSection({
|
|||
const theme = getPreparationPlanTheme(studyPlan.type);
|
||||
|
||||
return (
|
||||
<InterviewsLearningListCard
|
||||
<InterviewsStudyListCard
|
||||
key={studyPlan.type}
|
||||
completionCount={completionCount}
|
||||
isStarted={session != null}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import {
|
||||
categorizeFocusAreas,
|
||||
getFocusAreaTheme,
|
||||
categorizeFocusAreas_DEPRECATED,
|
||||
getFocusAreaTheme_DEPRECATED,
|
||||
} from '~/data/focus-areas/FocusAreas';
|
||||
|
||||
import InterviewsLearningListCard from '~/components/interviews/questions/listings/learning/InterviewsLearningListCard';
|
||||
import InterviewsStudyListCard from '~/components/interviews/questions/listings/learning/InterviewsStudyListCard';
|
||||
import InterviewsDashboardLearningSection from '~/components/interviews/revamp-dashboard/InterviewsDashboardLearningSection';
|
||||
import { useIntl } from '~/components/intl';
|
||||
import Text from '~/components/ui/Text';
|
||||
|
|
@ -20,7 +20,7 @@ export default function InterviewsDashboardPracticeByFocusAreasSection({
|
|||
questionListSessions,
|
||||
}: Props) {
|
||||
const intl = useIntl();
|
||||
const focusAreasCategories = categorizeFocusAreas(intl);
|
||||
const focusAreasCategories = categorizeFocusAreas_DEPRECATED(intl);
|
||||
|
||||
return (
|
||||
<InterviewsDashboardLearningSection
|
||||
|
|
@ -48,10 +48,10 @@ export default function InterviewsDashboardPracticeByFocusAreasSection({
|
|||
(session_) => session_.key === focusArea.type,
|
||||
);
|
||||
const completionCount = session?._count.progress;
|
||||
const theme = getFocusAreaTheme(focusArea.type);
|
||||
const theme = getFocusAreaTheme_DEPRECATED(focusArea.type);
|
||||
|
||||
return (
|
||||
<InterviewsLearningListCard
|
||||
<InterviewsStudyListCard
|
||||
key={focusArea.type}
|
||||
completionCount={completionCount}
|
||||
isStarted={session != null}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,56 @@
|
|||
// @ts-check
|
||||
|
||||
import { makeSource } from 'contentlayer/source-files';
|
||||
import remarkFrontmatter from 'remark-frontmatter';
|
||||
import remarkGfm from 'remark-gfm';
|
||||
import remarkMdxFrontmatter from 'remark-mdx-frontmatter';
|
||||
|
||||
import { BlogAuthorDocument } from '../components/blog/contentlayer/BlogAuthorDocument';
|
||||
import { BlogCategoryDocument } from '../components/blog/contentlayer/BlogCategoryDocument';
|
||||
import { BlogPostDocument } from '../components/blog/contentlayer/BlogPostDocument';
|
||||
import { BlogSeriesDocument } from '../components/blog/contentlayer/BlogSeriesDocument';
|
||||
import { BlogSubseriesDocument } from '../components/blog/contentlayer/BlogSubseriesDocument';
|
||||
import { JobsPostingDocument } from '../components/hiring/contentlayer/JobsPostingDocument';
|
||||
import { InterviewsListingBottomContentDocument } from '../components/interviews/questions/listings/InterviewsListingBottomContentDocument';
|
||||
import { InterviewsStudyListDocument } from '../components/interviews/questions/listings/learning/InterviewsStudyListDocument';
|
||||
import { ProjectsChallengeAPIWriteupDocument } from '../components/projects/contentlayer/ProjectsChallengeAPIWriteupDocument';
|
||||
import { ProjectsChallengeAppendixDocument } from '../components/projects/contentlayer/ProjectsChallengeAppendixDocument';
|
||||
import { ProjectsChallengeBriefDocument } from '../components/projects/contentlayer/ProjectsChallengeBriefDocument';
|
||||
import { ProjectsChallengeGuideDocument } from '../components/projects/contentlayer/ProjectsChallengeGuideDocument';
|
||||
import { ProjectsChallengeInfoDocument } from '../components/projects/contentlayer/ProjectsChallengeInfoDocument';
|
||||
import { ProjectsChallengeMetadataDocument } from '../components/projects/contentlayer/ProjectsChallengeMetadataDocument';
|
||||
import { ProjectsChallengeStyleGuideDocument } from '../components/projects/contentlayer/ProjectsChallengeStyleGuideDocument';
|
||||
import { ProjectsCommonGuideDocument } from '../components/projects/contentlayer/ProjectsCommonGuideDocument';
|
||||
import { ProjectsSkillInfoDocument } from '../components/projects/contentlayer/ProjectsSkillInfoDocument';
|
||||
import { ProjectsSkillMetadataDocument } from '../components/projects/contentlayer/ProjectsSkillMetadataDocument';
|
||||
import { ProjectsTrackInfoDocument } from '../components/projects/contentlayer/ProjectsTrackInfoDocument';
|
||||
import { ProjectsTrackMetadataDocument } from '../components/projects/contentlayer/ProjectsTrackMetadataDocument';
|
||||
|
||||
export default makeSource({
|
||||
contentDirPath: 'src/content',
|
||||
documentTypes: [
|
||||
BlogAuthorDocument,
|
||||
BlogCategoryDocument,
|
||||
BlogPostDocument,
|
||||
BlogSeriesDocument,
|
||||
BlogSubseriesDocument,
|
||||
InterviewsStudyListDocument,
|
||||
InterviewsListingBottomContentDocument,
|
||||
ProjectsCommonGuideDocument,
|
||||
ProjectsChallengeAppendixDocument,
|
||||
ProjectsChallengeBriefDocument,
|
||||
ProjectsChallengeGuideDocument,
|
||||
ProjectsChallengeInfoDocument,
|
||||
ProjectsChallengeMetadataDocument,
|
||||
ProjectsChallengeStyleGuideDocument,
|
||||
ProjectsChallengeAPIWriteupDocument,
|
||||
ProjectsSkillMetadataDocument,
|
||||
ProjectsSkillInfoDocument,
|
||||
ProjectsTrackMetadataDocument,
|
||||
ProjectsTrackInfoDocument,
|
||||
JobsPostingDocument,
|
||||
],
|
||||
mdx: {
|
||||
remarkPlugins: [remarkGfm, remarkFrontmatter, remarkMdxFrontmatter],
|
||||
},
|
||||
});
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
---
|
||||
name: Accessibility
|
||||
longName: Accessibility
|
||||
description: Targeted practice on Accessibility interview questions
|
||||
shortDescription: Practice developing inclusive and accessible web experiences.
|
||||
seoTitle: Practice Accessibility Interview Questions with Solutions
|
||||
seoDescription: Practice front end Accessibility interview questions on semantic HTML, ARIA, and screen readers. Code in-browser with curated solutions from ex-interviewers.
|
||||
socialTitle: Accessibility Interview Questions | GreatFrontEnd
|
||||
ranking: 999
|
||||
questionsAlgo: []
|
||||
questionsJavaScript: []
|
||||
questionsQuiz: []
|
||||
questionsSystemDesign: []
|
||||
questionsUserInterface:
|
||||
- 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
|
||||
---
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
---
|
||||
name: Async Operations
|
||||
longName: Async Operations
|
||||
description: Targeted practice on Async Operations interview questions
|
||||
shortDescription: Sharpen your skills in asynchronous programming by practicing the use of async/await, Promises, and callback functions.
|
||||
seoTitle: Practice Async Operations Interview Questions with Solutions
|
||||
seoDescription: Practice async operations interview questions on async / await, Promises, and callbacks. Code in-browser with quality solutions and tests from ex-interviewers.
|
||||
socialTitle: Async Operations Interview Questions | GreatFrontEnd
|
||||
ranking: 999
|
||||
questionsAlgo: []
|
||||
questionsJavaScript:
|
||||
- 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
|
||||
questionsQuiz: []
|
||||
questionsSystemDesign: []
|
||||
questionsUserInterface:
|
||||
- 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
|
||||
---
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
---
|
||||
name: Data Structures & Algorithms
|
||||
longName: Data Structures & Algorithms
|
||||
description: Targeted practice on Data Structures & Algorithms interview questions
|
||||
shortDescription: Hone your computer science fundamentals by implementing important data structures and algorithms from scratch.
|
||||
seoTitle: Practice Data Structures and Algorithms Interview Questions
|
||||
seoDescription: Practice data structures and algorithms interview questions in-browser with JavaScript / TypeScript solutions from ex-interviewers.
|
||||
socialTitle: Data Structures and Algorithms Interview Questions | GreatFrontEnd
|
||||
ranking: 999
|
||||
questionsAlgo:
|
||||
- stack
|
||||
- queue
|
||||
- merge-sort
|
||||
- quick-sort
|
||||
- heap-sort
|
||||
- topological-sort
|
||||
- insertion-sort
|
||||
- selection-sort
|
||||
- binary-search
|
||||
- depth-first-search
|
||||
- breadth-first-search
|
||||
questionsJavaScript:
|
||||
- data-merging
|
||||
- data-selection
|
||||
- event-emitter
|
||||
- event-emitter-ii
|
||||
- backbone-model
|
||||
- table-of-contents
|
||||
- unique-array
|
||||
questionsQuiz: []
|
||||
questionsSystemDesign: []
|
||||
questionsUserInterface:
|
||||
- transfer-list
|
||||
- transfer-list-ii
|
||||
- undoable-counter
|
||||
- wordle
|
||||
---
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
---
|
||||
name: Design System Components
|
||||
longName: Design System Components
|
||||
description: Targeted practice on Design System Components interview questions
|
||||
shortDescription: Elevate your front-end skills by practicing the creation of front end design system components.
|
||||
seoTitle: Practice Design System Components Interview Questions
|
||||
seoDescription: Practice design system components interview questions, including Tabs, Modals, Accordions, and Progress Bars. Code in-browser with solutions from ex-interviewers.
|
||||
socialTitle: Design System Components Interview Questions | GreatFrontEnd
|
||||
ranking: 999
|
||||
questionsAlgo: []
|
||||
questionsJavaScript: []
|
||||
questionsQuiz: []
|
||||
questionsSystemDesign:
|
||||
- image-carousel
|
||||
- dropdown-menu
|
||||
- modal-dialog
|
||||
questionsUserInterface:
|
||||
- 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
|
||||
---
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
name: DOM Manipulation
|
||||
longName: DOM Manipulation
|
||||
description: Targeted practice on DOM Manipulation interview questions
|
||||
shortDescription: Familiarize with selecting elements using CSS selectors, traverse the DOM hierarchy, and manipulate their properties, content, and styles.
|
||||
seoTitle: Practice DOM Manipulation Interview Questions with Solutions
|
||||
seoDescription: Practice DOM manipulation interview questions on CSS selectors, DOM traversal, and element manipulation. Code in-browser with solutions from ex-interviewers.
|
||||
socialTitle: DOM Manipulation Interview Questions | GreatFrontEnd
|
||||
ranking: 999
|
||||
questionsAlgo: []
|
||||
questionsJavaScript:
|
||||
- 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
|
||||
questionsQuiz: []
|
||||
questionsSystemDesign: []
|
||||
questionsUserInterface: []
|
||||
---
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
name: Forms
|
||||
longName: Forms
|
||||
description: Targeted practice on Forms interview questions
|
||||
shortDescription: Master the art of building interactive and user-friendly forms.
|
||||
seoTitle: Practice Forms Interview Questions with Solutions
|
||||
seoDescription: Practice form-related interview questions on form components, validation, and submission handling. Code in-browser with solutions from ex-interviewers.
|
||||
socialTitle: Forms Interview Questions | GreatFrontEnd
|
||||
ranking: 999
|
||||
questionsAlgo: []
|
||||
questionsJavaScript: []
|
||||
questionsQuiz: []
|
||||
questionsSystemDesign:
|
||||
- e-commerce-amazon
|
||||
questionsUserInterface:
|
||||
- auth-code-input
|
||||
- contact-form
|
||||
- flight-booker
|
||||
- mortgage-calculator
|
||||
- nested-checkboxes
|
||||
- signup-form
|
||||
- todo-list
|
||||
- temperature-converter
|
||||
- transfer-list-ii
|
||||
---
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
---
|
||||
name: JavaScript Polyfills
|
||||
longName: JavaScript Polyfills
|
||||
description: Targeted practice on JavaScript Polyfills interview questions
|
||||
shortDescription: Gain proficiency in front end fundamentals by implementing JavaScript and DOM APIs from scratch
|
||||
seoTitle: Practice JavaScript Polyfills Interview Questions with Solutions
|
||||
seoDescription: Practice JavaScript Polyfills interview questions by implementing JS and DOM APIs from scratch. Code in-browser with solutions by ex-interviewers
|
||||
socialTitle: JavaScript Polyfills Interview Questions | GreatFrontEnd
|
||||
ranking: 999
|
||||
questionsAlgo: []
|
||||
questionsJavaScript:
|
||||
- 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
|
||||
questionsQuiz: []
|
||||
questionsSystemDesign: []
|
||||
questionsUserInterface: []
|
||||
---
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
---
|
||||
name: Lodash Functions
|
||||
longName: Lodash Functions
|
||||
description: Targeted practice on Lodash Functions interview questions
|
||||
shortDescription: Strengthen your proficiency in JavaScript through writing Lodash functions from scratch.
|
||||
seoTitle: Practice Lodash Interview Questions with Solutions
|
||||
seoDescription: Practice Lodash interview questions, implementing functions to manipulate and transform data efficiently. Code in-browser with solutions from ex-interviewers.
|
||||
socialTitle: Lodash Functions Interview Questions | GreatFrontEnd
|
||||
ranking: 999
|
||||
questionsAlgo: []
|
||||
questionsJavaScript:
|
||||
- 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
|
||||
questionsQuiz: []
|
||||
questionsSystemDesign: []
|
||||
questionsUserInterface: []
|
||||
---
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
---
|
||||
name: State Management
|
||||
longName: State Management
|
||||
description: Targeted practice on State Management interview questions
|
||||
shortDescription: Train your skills in designing complex state and implementing operations to manipulate state.
|
||||
seoTitle: Practice State Management Interview Questions with Solutions
|
||||
seoDescription: Practice State Management interview questions that train your skills in complex state design and state manipulation. Code in-browser with solutions from ex-interviewers.
|
||||
socialTitle: State Management Interview Questions | GreatFrontEnd
|
||||
ranking: 999
|
||||
questionsAlgo: []
|
||||
questionsJavaScript: []
|
||||
questionsQuiz: []
|
||||
questionsSystemDesign: []
|
||||
questionsUserInterface:
|
||||
- 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
|
||||
---
|
||||
|
|
@ -2,7 +2,7 @@ import type { IntlShape } from 'react-intl';
|
|||
|
||||
import type {
|
||||
QuestionList_DEPRECATED,
|
||||
QuestionListTheme,
|
||||
QuestionListTheme_DEPRECATED,
|
||||
} from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
|
||||
import {
|
||||
|
|
@ -42,7 +42,8 @@ import {
|
|||
getFocusAreaThemeStateManagement,
|
||||
} from './items/FocusAreaStateManagement';
|
||||
|
||||
export type FocusAreaType =
|
||||
/** @deprecated */
|
||||
export type FocusAreaType_DEPRECATED =
|
||||
| 'accessibility'
|
||||
| 'async-operations'
|
||||
| 'data-structures-algorithms'
|
||||
|
|
@ -53,37 +54,51 @@ export type FocusAreaType =
|
|||
| 'lodash'
|
||||
| 'state-management';
|
||||
|
||||
// Can only contain serializable values as it's passed between the server-client boundary.
|
||||
export type FocusArea = QuestionList_DEPRECATED &
|
||||
/** @deprecated Can only contain serializable values as it's passed between the server-client boundary. */
|
||||
export type FocusArea_DEPRECATED = QuestionList_DEPRECATED &
|
||||
Readonly<{
|
||||
type: FocusAreaType;
|
||||
type: FocusAreaType_DEPRECATED;
|
||||
}>;
|
||||
|
||||
export type FocusAreas = Record<FocusAreaType, FocusArea>;
|
||||
/** @deprecated */
|
||||
export type FocusAreas_DEPRECATED = Record<
|
||||
FocusAreaType_DEPRECATED,
|
||||
FocusArea_DEPRECATED
|
||||
>;
|
||||
|
||||
export function getFocusAreas(intl: IntlShape): FocusAreas {
|
||||
const focusAreas: FocusAreas = {
|
||||
accessibility: getFocusArea('accessibility', intl),
|
||||
'async-operations': getFocusArea('async-operations', intl),
|
||||
'data-structures-algorithms': getFocusArea(
|
||||
/** @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('design-system-components', intl),
|
||||
'dom-manipulation': getFocusArea('dom-manipulation', intl),
|
||||
forms: getFocusArea('forms', intl),
|
||||
'javascript-polyfills': getFocusArea('javascript-polyfills', intl),
|
||||
lodash: getFocusArea('lodash', intl),
|
||||
'state-management': getFocusArea('state-management', 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;
|
||||
}
|
||||
|
||||
export function getFocusArea(
|
||||
focusArea: FocusAreaType,
|
||||
/** @deprecated */
|
||||
export function getFocusArea_DEPRECATED(
|
||||
focusArea: FocusAreaType_DEPRECATED,
|
||||
intl: IntlShape,
|
||||
): FocusArea {
|
||||
): FocusArea_DEPRECATED {
|
||||
switch (focusArea) {
|
||||
case 'accessibility':
|
||||
return getFocusAreaAccessibility(intl);
|
||||
|
|
@ -106,23 +121,33 @@ export function getFocusArea(
|
|||
}
|
||||
}
|
||||
|
||||
export function getFocusAreaThemes(): Record<FocusAreaType, QuestionListTheme> {
|
||||
export function getFocusAreaThemes_DEPRECATED(): Record<
|
||||
FocusAreaType_DEPRECATED,
|
||||
QuestionListTheme_DEPRECATED
|
||||
> {
|
||||
return {
|
||||
accessibility: getFocusAreaTheme('accessibility'),
|
||||
'async-operations': getFocusAreaTheme('async-operations'),
|
||||
'data-structures-algorithms': getFocusAreaTheme(
|
||||
accessibility: getFocusAreaTheme_DEPRECATED('accessibility'),
|
||||
'async-operations': getFocusAreaTheme_DEPRECATED('async-operations'),
|
||||
'data-structures-algorithms': getFocusAreaTheme_DEPRECATED(
|
||||
'data-structures-algorithms',
|
||||
),
|
||||
'design-system-components': getFocusAreaTheme('design-system-components'),
|
||||
'dom-manipulation': getFocusAreaTheme('dom-manipulation'),
|
||||
forms: getFocusAreaTheme('forms'),
|
||||
'javascript-polyfills': getFocusAreaTheme('javascript-polyfills'),
|
||||
lodash: getFocusAreaTheme('lodash'),
|
||||
'state-management': getFocusAreaTheme('state-management'),
|
||||
'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'),
|
||||
};
|
||||
}
|
||||
|
||||
export function getFocusAreaTheme(focusArea: FocusAreaType): QuestionListTheme {
|
||||
/** @deprecated */
|
||||
export function getFocusAreaTheme_DEPRECATED(
|
||||
focusArea: string,
|
||||
): QuestionListTheme_DEPRECATED {
|
||||
switch (focusArea) {
|
||||
case 'accessibility':
|
||||
return getFocusAreaThemeAccessibility();
|
||||
|
|
@ -142,11 +167,14 @@ export function getFocusAreaTheme(focusArea: FocusAreaType): QuestionListTheme {
|
|||
return getFocusAreaThemeJavaScriptPolyfills();
|
||||
case 'state-management':
|
||||
return getFocusAreaThemeStateManagement();
|
||||
default:
|
||||
throw Error('No such focus area');
|
||||
}
|
||||
}
|
||||
|
||||
export function categorizeFocusAreas(intl: IntlShape) {
|
||||
const focusAreas = getFocusAreas(intl);
|
||||
/** @deprecated */
|
||||
export function categorizeFocusAreas_DEPRECATED(intl: IntlShape) {
|
||||
const focusAreas = getFocusAreas_DEPRECATED(intl);
|
||||
|
||||
return [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,17 +1,12 @@
|
|||
import { useIntl } from '~/components/intl';
|
||||
|
||||
import type { FocusAreaType } from './FocusAreas';
|
||||
import { getFocusArea } from './FocusAreas';
|
||||
import { getFocusAreas } from './FocusAreas';
|
||||
import { getFocusAreas_DEPRECATED } from './FocusAreas';
|
||||
|
||||
export function useFocusAreas() {
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
export function useFocusAreas_DEPRECATED() {
|
||||
const intl = useIntl();
|
||||
|
||||
return getFocusAreas(intl);
|
||||
}
|
||||
|
||||
export function useFocusArea(focusArea: FocusAreaType) {
|
||||
const intl = useIntl();
|
||||
|
||||
return getFocusArea(focusArea, intl);
|
||||
return getFocusAreas_DEPRECATED(intl);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
import { BiUniversalAccess } from 'react-icons/bi';
|
||||
import type { IntlShape } from 'react-intl';
|
||||
|
||||
import type { QuestionListTheme } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import type { QuestionListTheme_DEPRECATED } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import type { ThemeGradient } from '~/components/ui/theme';
|
||||
|
||||
import type { FocusArea } from '../FocusAreas';
|
||||
import type { FocusArea_DEPRECATED } from '../FocusAreas';
|
||||
|
||||
export function getFocusAreaAccessibility(intl: IntlShape): FocusArea {
|
||||
export function getFocusAreaAccessibility(
|
||||
intl: IntlShape,
|
||||
): FocusArea_DEPRECATED {
|
||||
return {
|
||||
description: intl.formatMessage({
|
||||
defaultMessage: 'Targeted practice on Accessibility interview questions',
|
||||
|
|
@ -79,7 +81,7 @@ const gradient: ThemeGradient<'#f953c6', '#b91d73'> = {
|
|||
startColor: '#f953c6',
|
||||
};
|
||||
|
||||
export function getFocusAreaThemeAccessibility(): QuestionListTheme {
|
||||
export function getFocusAreaThemeAccessibility(): QuestionListTheme_DEPRECATED {
|
||||
return {
|
||||
gradient,
|
||||
iconOutline: BiUniversalAccess,
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
import { RiRefreshLine } from 'react-icons/ri';
|
||||
import type { IntlShape } from 'react-intl';
|
||||
|
||||
import type { QuestionListTheme } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import type { QuestionListTheme_DEPRECATED } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import type { ThemeGradient } from '~/components/ui/theme';
|
||||
|
||||
import type { FocusArea } from '../FocusAreas';
|
||||
import type { FocusArea_DEPRECATED } from '../FocusAreas';
|
||||
|
||||
export function getFocusAreaAsyncOperations(intl: IntlShape): FocusArea {
|
||||
export function getFocusAreaAsyncOperations(
|
||||
intl: IntlShape,
|
||||
): FocusArea_DEPRECATED {
|
||||
return {
|
||||
description: intl.formatMessage({
|
||||
defaultMessage:
|
||||
|
|
@ -102,7 +104,7 @@ const gradient: ThemeGradient<'#8E2DE2', '#4A00E0'> = {
|
|||
startColor: '#8E2DE2',
|
||||
};
|
||||
|
||||
export function getFocusAreaThemeAsyncOperations(): QuestionListTheme {
|
||||
export function getFocusAreaThemeAsyncOperations(): QuestionListTheme_DEPRECATED {
|
||||
return {
|
||||
gradient,
|
||||
iconOutline: RiRefreshLine,
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
import { RiWindowFill } from 'react-icons/ri';
|
||||
import type { IntlShape } from 'react-intl';
|
||||
|
||||
import type { QuestionListTheme } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import type { QuestionListTheme_DEPRECATED } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import type { ThemeGradient } from '~/components/ui/theme';
|
||||
|
||||
import type { FocusArea } from '../FocusAreas';
|
||||
import type { FocusArea_DEPRECATED } from '../FocusAreas';
|
||||
|
||||
export function getFocusAreaDOMManipulation(intl: IntlShape): FocusArea {
|
||||
export function getFocusAreaDOMManipulation(
|
||||
intl: IntlShape,
|
||||
): FocusArea_DEPRECATED {
|
||||
return {
|
||||
description: intl.formatMessage({
|
||||
defaultMessage:
|
||||
|
|
@ -78,7 +80,7 @@ const gradient: ThemeGradient<'#bc4e9c', '#f80759'> = {
|
|||
startColor: '#bc4e9c',
|
||||
};
|
||||
|
||||
export function getFocusAreaThemeDOMManipulation(): QuestionListTheme {
|
||||
export function getFocusAreaThemeDOMManipulation(): QuestionListTheme_DEPRECATED {
|
||||
return {
|
||||
gradient,
|
||||
iconOutline: RiWindowFill,
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
import { TbBinaryTree } from 'react-icons/tb';
|
||||
import type { IntlShape } from 'react-intl';
|
||||
|
||||
import type { QuestionListTheme } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
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 } from '../FocusAreas';
|
||||
import type { FocusArea_DEPRECATED } from '../FocusAreas';
|
||||
|
||||
export function getFocusAreaDataStructuresAlgorithms(
|
||||
intl: IntlShape,
|
||||
): FocusArea {
|
||||
): FocusArea_DEPRECATED {
|
||||
return {
|
||||
description: intl.formatMessage(
|
||||
{
|
||||
|
|
@ -101,7 +101,7 @@ const gradient: ThemeGradient<'#50C9C3', '#96DEDA'> = {
|
|||
startColor: '#50C9C3',
|
||||
};
|
||||
|
||||
export function getFocusAreaThemeDataStructuresAlgorithms(): QuestionListTheme {
|
||||
export function getFocusAreaThemeDataStructuresAlgorithms(): QuestionListTheme_DEPRECATED {
|
||||
return {
|
||||
gradient,
|
||||
iconOutline: TbBinaryTree,
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
import { RiDashboardLine } from 'react-icons/ri';
|
||||
import type { IntlShape } from 'react-intl';
|
||||
|
||||
import type { QuestionListTheme } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import type { QuestionListTheme_DEPRECATED } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import type { ThemeGradient } from '~/components/ui/theme';
|
||||
|
||||
import type { FocusArea } from '../FocusAreas';
|
||||
import type { FocusArea_DEPRECATED } from '../FocusAreas';
|
||||
|
||||
export function getFocusAreaDesignSystemComponents(intl: IntlShape): FocusArea {
|
||||
export function getFocusAreaDesignSystemComponents(
|
||||
intl: IntlShape,
|
||||
): FocusArea_DEPRECATED {
|
||||
return {
|
||||
description: intl.formatMessage({
|
||||
defaultMessage:
|
||||
|
|
@ -80,7 +82,7 @@ const gradient: ThemeGradient<'#FF5F6D', '#FFC371'> = {
|
|||
startColor: '#FF5F6D',
|
||||
};
|
||||
|
||||
export function getFocusAreaThemeDesignSystemComponents(): QuestionListTheme {
|
||||
export function getFocusAreaThemeDesignSystemComponents(): QuestionListTheme_DEPRECATED {
|
||||
return {
|
||||
gradient,
|
||||
iconOutline: RiDashboardLine,
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
import { TbForms } from 'react-icons/tb';
|
||||
import type { IntlShape } from 'react-intl';
|
||||
|
||||
import type { QuestionListTheme } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import type { QuestionListTheme_DEPRECATED } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import type { ThemeGradient } from '~/components/ui/theme';
|
||||
|
||||
import type { FocusArea } from '../FocusAreas';
|
||||
import type { FocusArea_DEPRECATED } from '../FocusAreas';
|
||||
|
||||
export function getFocusAreaForms(intl: IntlShape): FocusArea {
|
||||
export function getFocusAreaForms(intl: IntlShape): FocusArea_DEPRECATED {
|
||||
return {
|
||||
description: intl.formatMessage({
|
||||
defaultMessage: 'Targeted practice on Forms interview questions',
|
||||
|
|
@ -75,7 +75,7 @@ const gradient: ThemeGradient<'#56ab2f', '#a8e063'> = {
|
|||
startColor: '#56ab2f',
|
||||
};
|
||||
|
||||
export function getFocusAreaThemeForms(): QuestionListTheme {
|
||||
export function getFocusAreaThemeForms(): QuestionListTheme_DEPRECATED {
|
||||
return {
|
||||
gradient,
|
||||
iconOutline: TbForms,
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
import { RiJavascriptFill } from 'react-icons/ri';
|
||||
import type { IntlShape } from 'react-intl';
|
||||
|
||||
import type { QuestionListTheme } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import type { QuestionListTheme_DEPRECATED } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import type { ThemeGradient } from '~/components/ui/theme';
|
||||
|
||||
import type { FocusArea } from '../FocusAreas';
|
||||
import type { FocusArea_DEPRECATED } from '../FocusAreas';
|
||||
|
||||
export function getFocusAreaJavaScriptPolyfills(intl: IntlShape): FocusArea {
|
||||
export function getFocusAreaJavaScriptPolyfills(
|
||||
intl: IntlShape,
|
||||
): FocusArea_DEPRECATED {
|
||||
return {
|
||||
description: intl.formatMessage({
|
||||
defaultMessage:
|
||||
|
|
@ -95,7 +97,7 @@ const gradient: ThemeGradient<'#f7df1e', '#f7df1e'> = {
|
|||
startColor: '#f7df1e',
|
||||
};
|
||||
|
||||
export function getFocusAreaThemeJavaScriptPolyfills(): QuestionListTheme {
|
||||
export function getFocusAreaThemeJavaScriptPolyfills(): QuestionListTheme_DEPRECATED {
|
||||
return {
|
||||
gradient,
|
||||
iconOutline: RiJavascriptFill,
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
import { SiLodash } from 'react-icons/si';
|
||||
import type { IntlShape } from 'react-intl';
|
||||
|
||||
import type { QuestionListTheme } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import type { QuestionListTheme_DEPRECATED } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import type { ThemeGradient } from '~/components/ui/theme';
|
||||
|
||||
import type { FocusArea } from '../FocusAreas';
|
||||
import type { FocusArea_DEPRECATED } from '../FocusAreas';
|
||||
|
||||
export function getFocusAreaLodash(intl: IntlShape): FocusArea {
|
||||
export function getFocusAreaLodash(intl: IntlShape): FocusArea_DEPRECATED {
|
||||
return {
|
||||
description: intl.formatMessage({
|
||||
defaultMessage:
|
||||
|
|
@ -96,7 +96,7 @@ const gradient: ThemeGradient<'#7474BF', '#348AC7'> = {
|
|||
startColor: '#7474BF',
|
||||
};
|
||||
|
||||
export function getFocusAreaThemeLodash(): QuestionListTheme {
|
||||
export function getFocusAreaThemeLodash(): QuestionListTheme_DEPRECATED {
|
||||
return {
|
||||
gradient,
|
||||
iconOutline: SiLodash,
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
import { RiFlowChart } from 'react-icons/ri';
|
||||
import type { IntlShape } from 'react-intl';
|
||||
|
||||
import type { QuestionListTheme } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import type { QuestionListTheme_DEPRECATED } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import type { ThemeGradient } from '~/components/ui/theme';
|
||||
|
||||
import type { FocusArea } from '../FocusAreas';
|
||||
import type { FocusArea_DEPRECATED } from '../FocusAreas';
|
||||
|
||||
export function getFocusAreaStateManagement(intl: IntlShape): FocusArea {
|
||||
export function getFocusAreaStateManagement(
|
||||
intl: IntlShape,
|
||||
): FocusArea_DEPRECATED {
|
||||
return {
|
||||
description: intl.formatMessage({
|
||||
defaultMessage:
|
||||
|
|
@ -85,7 +87,7 @@ const gradient: ThemeGradient<'#4e54c8', '#8f94fb'> = {
|
|||
startColor: '#4e54c8',
|
||||
};
|
||||
|
||||
export function getFocusAreaThemeStateManagement(): QuestionListTheme {
|
||||
export function getFocusAreaThemeStateManagement(): QuestionListTheme_DEPRECATED {
|
||||
return {
|
||||
gradient,
|
||||
iconOutline: RiFlowChart,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import type { IntlShape } from 'react-intl';
|
|||
|
||||
import type {
|
||||
QuestionList_DEPRECATED,
|
||||
QuestionListTheme,
|
||||
QuestionListTheme_DEPRECATED,
|
||||
} from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
|
||||
import {
|
||||
|
|
@ -79,7 +79,7 @@ export function getPreparationPlan(
|
|||
|
||||
export function getPreparationPlanThemes(): Record<
|
||||
PreparationPlanType,
|
||||
QuestionListTheme
|
||||
QuestionListTheme_DEPRECATED
|
||||
> {
|
||||
return {
|
||||
blind75: getPreparationPlanTheme('greatfrontend75'),
|
||||
|
|
@ -92,7 +92,7 @@ export function getPreparationPlanThemes(): Record<
|
|||
|
||||
export function getPreparationPlanTheme(
|
||||
planType: PreparationPlanType,
|
||||
): QuestionListTheme {
|
||||
): QuestionListTheme_DEPRECATED {
|
||||
switch (planType) {
|
||||
case 'one-week':
|
||||
return getPreparationPlanThemeOneWeek();
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { RiEye2Fill, RiEye2Line } from 'react-icons/ri';
|
||||
import type { IntlShape } from 'react-intl';
|
||||
|
||||
import type { QuestionListTheme } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import type { QuestionListTheme_DEPRECATED } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import { type ThemeGradient } from '~/components/ui/theme';
|
||||
|
||||
import { PreparationPlanQuizImportanceHighJavaScript } from './PreparationPlanQuizQuestions';
|
||||
|
|
@ -99,7 +99,7 @@ const gradient: ThemeGradient<'#B7B1FF', '#4B468B'> = {
|
|||
startColor: '#B7B1FF',
|
||||
};
|
||||
|
||||
export function getPreparationPlanThemeBlind75(): QuestionListTheme {
|
||||
export function getPreparationPlanThemeBlind75(): QuestionListTheme_DEPRECATED {
|
||||
return {
|
||||
gradient,
|
||||
iconOutline: RiEye2Line,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { RiStarFill, RiStarLine } from 'react-icons/ri';
|
||||
import type { IntlShape } from 'react-intl';
|
||||
|
||||
import type { QuestionListTheme } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import type { QuestionListTheme_DEPRECATED } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import { type ThemeGradient } from '~/components/ui/theme';
|
||||
|
||||
import { PreparationPlanQuizImportanceHighJavaScript } from './PreparationPlanQuizQuestions';
|
||||
|
|
@ -98,7 +98,7 @@ const gradient: ThemeGradient<'#B7B1FF', '#4B468B'> = {
|
|||
startColor: '#B7B1FF',
|
||||
};
|
||||
|
||||
export function getPreparationPlanThemeGFE75(): QuestionListTheme {
|
||||
export function getPreparationPlanThemeGFE75(): QuestionListTheme_DEPRECATED {
|
||||
return {
|
||||
customIcon: PreparationGFE75Logo,
|
||||
gradient,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { RiFireFill, RiFireLine } from 'react-icons/ri';
|
||||
import type { IntlShape } from 'react-intl';
|
||||
|
||||
import type { QuestionListTheme } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import type { QuestionListTheme_DEPRECATED } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import type { ThemeGradient } from '~/components/ui/theme';
|
||||
|
||||
import {
|
||||
|
|
@ -115,7 +115,7 @@ const gradient: ThemeGradient<'#bc4e9c', '#f80759'> = {
|
|||
startColor: '#bc4e9c',
|
||||
};
|
||||
|
||||
export function getPreparationPlanThemeOneMonth(): QuestionListTheme {
|
||||
export function getPreparationPlanThemeOneMonth(): QuestionListTheme_DEPRECATED {
|
||||
return {
|
||||
gradient,
|
||||
iconOutline: RiFireLine,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { RiFlashlightFill, RiFlashlightLine } from 'react-icons/ri';
|
||||
import type { IntlShape } from 'react-intl';
|
||||
|
||||
import type { QuestionListTheme } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import type { QuestionListTheme_DEPRECATED } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import type { ThemeGradient } from '~/components/ui/theme';
|
||||
|
||||
import {
|
||||
|
|
@ -92,7 +92,7 @@ const gradient: ThemeGradient<'#f7ff00', '#db36a4'> = {
|
|||
startColor: '#f7ff00',
|
||||
};
|
||||
|
||||
export function getPreparationPlanThemeOneWeek(): QuestionListTheme {
|
||||
export function getPreparationPlanThemeOneWeek(): QuestionListTheme_DEPRECATED {
|
||||
return {
|
||||
gradient,
|
||||
iconOutline: RiFlashlightLine,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { RiStarFill, RiStarLine } from 'react-icons/ri';
|
||||
import type { IntlShape } from 'react-intl';
|
||||
|
||||
import type { QuestionListTheme } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import type { QuestionListTheme_DEPRECATED } from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
import type { ThemeGradient } from '~/components/ui/theme';
|
||||
|
||||
import {
|
||||
|
|
@ -138,7 +138,7 @@ const gradient: ThemeGradient<'#7F00FF', '#E100FF'> = {
|
|||
startColor: '#7F00FF',
|
||||
};
|
||||
|
||||
export function getPreparationPlanThemeThreeMonths(): QuestionListTheme {
|
||||
export function getPreparationPlanThemeThreeMonths(): QuestionListTheme_DEPRECATED {
|
||||
return {
|
||||
gradient,
|
||||
iconOutline: RiStarLine,
|
||||
|
|
|
|||
|
|
@ -1,23 +1,29 @@
|
|||
import type {
|
||||
QuestionList_DEPRECATED,
|
||||
QuestionListTheme,
|
||||
QuestionListTheme_DEPRECATED,
|
||||
} from '~/components/interviews/questions/common/QuestionsTypes';
|
||||
|
||||
import { getFocusAreaThemes } from '../focus-areas/FocusAreas';
|
||||
import { useFocusAreas } from '../focus-areas/FocusAreasHooks';
|
||||
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(): Record<string, QuestionList_DEPRECATED> {
|
||||
export function useQuestionLists_DEPRECATED(): Record<
|
||||
string,
|
||||
QuestionList_DEPRECATED
|
||||
> {
|
||||
const plans = usePreparationPlans();
|
||||
const focusAreas = useFocusAreas();
|
||||
const focusAreas = useFocusAreas_DEPRECATED();
|
||||
|
||||
return { ...plans, ...focusAreas };
|
||||
}
|
||||
|
||||
export function getQuestionListThemes(): Record<string, QuestionListTheme> {
|
||||
export function getQuestionListThemes(): Record<
|
||||
string,
|
||||
QuestionListTheme_DEPRECATED
|
||||
> {
|
||||
const planThemes = getPreparationPlanThemes();
|
||||
const focusAreaThemes = getFocusAreaThemes();
|
||||
const focusAreaThemes = getFocusAreaThemes_DEPRECATED();
|
||||
|
||||
return { ...planThemes, ...focusAreaThemes };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -266,6 +266,12 @@ export function roundQuestionCountToNearestTen(count: number) {
|
|||
return Math.floor(count / 10) * 10;
|
||||
}
|
||||
|
||||
export function flattenQuestionFormatMetadata(
|
||||
questions: Record<QuestionFormat, ReadonlyArray<QuestionMetadata>>,
|
||||
): ReadonlyArray<QuestionMetadata> {
|
||||
return Object.values(questions).flat();
|
||||
}
|
||||
|
||||
export function countNumberOfQuestionsInList(
|
||||
questions: Record<QuestionFormat, ReadonlyArray<QuestionSlug>>,
|
||||
): number {
|
||||
|
|
|
|||
|
|
@ -1,17 +0,0 @@
|
|||
import type { InterviewsLearningList } from 'contentlayer/generated';
|
||||
|
||||
import { allInterviewsLearningLists } from '~/../.contentlayer/generated/InterviewsLearningList/_index.mjs';
|
||||
|
||||
export async function fetchInterviewsLearningList(slug: string) {
|
||||
return allInterviewsLearningLists.find((content) => content.slug === slug) as
|
||||
| InterviewsLearningList
|
||||
| undefined;
|
||||
}
|
||||
|
||||
export async function fetchInterviewsLearningLists(
|
||||
categoryParam: InterviewsLearningList['category'],
|
||||
): Promise<ReadonlyArray<InterviewsLearningList>> {
|
||||
return (
|
||||
allInterviewsLearningLists as ReadonlyArray<InterviewsLearningList>
|
||||
).filter(({ category }) => categoryParam === category);
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
import type { InterviewsStudyList } from 'contentlayer/generated';
|
||||
|
||||
import { allInterviewsStudyLists } from '~/../.contentlayer/generated/InterviewsStudyList/_index.mjs';
|
||||
|
||||
export async function fetchInterviewsStudyList(
|
||||
slug: string,
|
||||
): Promise<InterviewsStudyList | undefined> {
|
||||
return (allInterviewsStudyLists as ReadonlyArray<InterviewsStudyList>).find(
|
||||
(content) => content.slug === slug,
|
||||
);
|
||||
}
|
||||
|
||||
export async function fetchInterviewsStudyLists(
|
||||
categoryParam: InterviewsStudyList['category'],
|
||||
): Promise<ReadonlyArray<InterviewsStudyList>> {
|
||||
return (allInterviewsStudyLists as ReadonlyArray<InterviewsStudyList>).filter(
|
||||
({ category }) => categoryParam === category,
|
||||
);
|
||||
}
|
||||
|
|
@ -1163,10 +1163,6 @@
|
|||
"defaultMessage": "Annual plan",
|
||||
"description": "Title of annual pricing plan"
|
||||
},
|
||||
"6TG+jF": {
|
||||
"defaultMessage": "The one-stop to prepare well for your {company} front end interviews.",
|
||||
"description": "Description for company guides detail page"
|
||||
},
|
||||
"6U52IB": {
|
||||
"defaultMessage": "FAQ",
|
||||
"description": "Title for FAQ section on Projects project page"
|
||||
|
|
@ -4411,10 +4407,6 @@
|
|||
"defaultMessage": "Holistic front end skill roadmap",
|
||||
"description": "Title of 'Roadmap of front end skills' sub-feature in Projects marketing page"
|
||||
},
|
||||
"Qe4ww/": {
|
||||
"defaultMessage": "Discover focus areas tailored to your needs to help you prepare for your upcoming technical interviews.",
|
||||
"description": "Description for focus areas page"
|
||||
},
|
||||
"QeQWqZ": {
|
||||
"defaultMessage": "Explore component tracks",
|
||||
"description": "Recommended action for new projects platform user"
|
||||
|
|
@ -5064,7 +5056,7 @@
|
|||
"description": "Coding questions long title"
|
||||
},
|
||||
"UET3FT": {
|
||||
"defaultMessage": "Front End Interview Focus Areas—Accessibility, Forms and more",
|
||||
"defaultMessage": "Front End Interview Focus Areas — Accessibility, Forms and more",
|
||||
"description": "Page title for focus areas listing"
|
||||
},
|
||||
"UISwUX": {
|
||||
|
|
|
|||
Loading…
Reference in New Issue