├── src ├── lib │ ├── analytics │ │ ├── events │ │ │ └── index.ts │ │ ├── script-providers │ │ │ ├── index.ts │ │ │ └── yandex.tsx │ │ ├── providers │ │ │ ├── index.ts │ │ │ ├── console.ts │ │ │ ├── metrika.ts │ │ │ └── posthog.ts │ │ ├── trigger.ts │ │ └── index.ts │ ├── utils │ │ ├── focus-ring.ts │ │ ├── tw-merge.ts │ │ ├── index.ts │ │ ├── translators.ts │ │ ├── get-lesson-label.ts │ │ ├── get-media-source.ts │ │ ├── format-date.ts │ │ └── get-browser-icon.ts │ └── cookie.ts ├── components │ ├── account │ │ ├── security │ │ │ └── security.tsx │ │ ├── settings │ │ │ ├── preferences.tsx │ │ │ ├── subscription.tsx │ │ │ ├── account-form.tsx │ │ │ ├── profile-form.tsx │ │ │ ├── settings.tsx │ │ │ ├── account-actions.tsx │ │ │ ├── avatar-form.tsx │ │ │ └── auto-billing-form.tsx │ │ ├── sessions │ │ │ ├── remove-all-sessions.tsx │ │ │ ├── remove-session.tsx │ │ │ ├── sessions.tsx │ │ │ └── session-item.tsx │ │ ├── connections │ │ │ └── unlink-provider.tsx │ │ └── progress │ │ │ ├── progress.tsx │ │ │ ├── courses-list.tsx │ │ │ ├── courses-tab.tsx │ │ │ └── user-stats.tsx │ ├── icons │ │ ├── index.tsx │ │ ├── tbank-icon.tsx │ │ ├── yoomoney-icon.tsx │ │ ├── sberbank-icon.tsx │ │ └── sbp-icon.tsx │ ├── ui │ │ ├── skeleton.tsx │ │ ├── label.tsx │ │ ├── separator.tsx │ │ ├── progress.tsx │ │ ├── switch.tsx │ │ ├── avatar.tsx │ │ ├── radio-group.tsx │ │ ├── badge.tsx │ │ ├── scroll-area.tsx │ │ ├── alert.tsx │ │ ├── card.tsx │ │ ├── accordion.tsx │ │ ├── input.tsx │ │ ├── input-otp.tsx │ │ └── button.tsx │ ├── shared │ │ ├── heading.tsx │ │ ├── player.tsx │ │ ├── ellipsis-loader.tsx │ │ ├── captcha.tsx │ │ ├── sonner.tsx │ │ ├── course-progress.tsx │ │ └── confirm-dialog.tsx │ ├── lesson │ │ ├── lesson-container.tsx │ │ ├── lesson-player.tsx │ │ └── lesson-complete-button.tsx │ ├── layout │ │ ├── nav-links.tsx │ │ ├── user-navigation.tsx │ │ └── header.tsx │ ├── home │ │ ├── popular.tsx │ │ ├── telegram-cta.tsx │ │ └── features.tsx │ ├── auth │ │ ├── verify-email.tsx │ │ ├── passkey-login-button.tsx │ │ └── auth-social.tsx │ └── course │ │ ├── course-content.tsx │ │ ├── course-card.tsx │ │ ├── course-actions.tsx │ │ ├── course-details.tsx │ │ └── course-lessons.tsx ├── hooks │ ├── index.ts │ ├── useAuth.ts │ ├── useFingerprint.ts │ └── useCurrent.ts ├── constants │ ├── index.ts │ ├── app.ts │ ├── payment-icons.ts │ ├── mfa-methods.ts │ ├── seo.ts │ ├── routes.ts │ └── sso-providers.ts ├── app │ ├── loading.tsx │ ├── (public) │ │ ├── premium │ │ │ └── page.tsx │ │ ├── page.tsx │ │ ├── layout.tsx │ │ └── courses │ │ │ ├── page.tsx │ │ │ └── [slug] │ │ │ └── page.tsx │ ├── auth │ │ ├── login │ │ │ └── page.tsx │ │ ├── register │ │ │ └── page.tsx │ │ ├── recovery │ │ │ ├── page.tsx │ │ │ └── [token] │ │ │ │ └── page.tsx │ │ ├── verify │ │ │ └── [token] │ │ │ │ └── page.tsx │ │ ├── callback │ │ │ └── page.tsx │ │ └── telegram-oauth-finish │ │ │ └── page.tsx │ ├── account │ │ ├── page.tsx │ │ ├── sessions │ │ │ └── page.tsx │ │ ├── settings │ │ │ └── page.tsx │ │ ├── connections │ │ │ └── page.tsx │ │ └── layout.tsx │ ├── payment │ │ └── success │ │ │ └── page.tsx │ ├── robots.ts │ ├── sitemap.ts │ ├── manifest.ts │ └── not-found.tsx ├── providers │ ├── index.ts │ ├── theme-provider.tsx │ ├── analytics-provider.tsx │ ├── course-provider.tsx │ ├── tanstack-query-provider.tsx │ ├── account-provider.tsx │ └── fingerprint-provider.tsx ├── api │ ├── requests │ │ ├── restriction.ts │ │ ├── index.ts │ │ ├── payment.ts │ │ ├── progress.ts │ │ ├── lesson.ts │ │ ├── session.ts │ │ ├── passkey.ts │ │ ├── users.ts │ │ ├── course.ts │ │ ├── account.ts │ │ ├── sso.ts │ │ └── mfa.ts │ ├── generated │ │ ├── changeEmailRequest.ts │ │ ├── patchUserRequest.ts │ │ ├── createCourseRequest.ts │ │ ├── createCourseResponse.ts │ │ ├── createLessonResponse.ts │ │ ├── initPaymentResponse.ts │ │ ├── ssoControllerCallbackParams.ts │ │ ├── generateDownloadLinkResponse.ts │ │ ├── ssoConnectResponse.ts │ │ ├── ssoLoginResponse.ts │ │ ├── totpDisableRequest.ts │ │ ├── heleketPaymentWebhookResponseFrom.ts │ │ ├── createLessonRequest.ts │ │ ├── heleketPaymentConvertResponseCommission.ts │ │ ├── ssoLoginRequest.ts │ │ ├── heleketPaymentWebhookResponseTransferId.ts │ │ ├── sendPasswordResetRequest.ts │ │ ├── createProgressRequest.ts │ │ ├── createUserResponse.ts │ │ ├── heleketPaymentWebhookResponseAdditionalData.ts │ │ ├── heleketPaymentWebhookResponsePaymentAmount.ts │ │ ├── heleketPaymentWebhookResponseWalletAddressUuid.ts │ │ ├── lastLessonResponse.ts │ │ ├── loginSessionResponse.ts │ │ ├── passwordResetRequest.ts │ │ ├── registrationsResponse.ts │ │ ├── telegramAuthResponse.ts │ │ ├── totpGenerateSecretResponse.ts │ │ ├── heleketPaymentWebhookResponseTxid.ts │ │ ├── meProgressResponseLastLesson.ts │ │ ├── heleketPaymentWebhookResponseMerchantAmount.ts │ │ ├── sessionControllerLogin200.ts │ │ ├── totpEnableRequest.ts │ │ ├── createProgressResponse.ts │ │ ├── sessionControllerLoginAdmin200.ts │ │ ├── loginMfaResponse.ts │ │ ├── initPaymentRequest.ts │ │ ├── statisticsResponse.ts │ │ ├── changePasswordRequest.ts │ │ ├── mfaStatusResponse.ts │ │ ├── mfaControllerVerifyBody.ts │ │ ├── passkeyResponse.ts │ │ ├── activeRestrictionResponse.ts │ │ ├── heleketPaymentWebhookResponseType.ts │ │ ├── loginRequest.ts │ │ ├── leaderResponse.ts │ │ ├── ssoStatusResponse.ts │ │ ├── createRestrictionRequest.ts │ │ ├── sessionResponse.ts │ │ ├── createUserRequest.ts │ │ ├── createRestrictionRequestReason.ts │ │ ├── paymentMethodResponse.ts │ │ ├── progressResponse.ts │ │ ├── coursesResponse.ts │ │ ├── initPaymentRequestMethod.ts │ │ ├── accountResponse.ts │ │ ├── paymentMethodResponseId.ts │ │ ├── userResponse.ts │ │ ├── heleketPaymentConvertResponse.ts │ │ ├── heleketPaymentWebhookResponseStatus.ts │ │ ├── meStatisticsResponse.ts │ │ ├── telegramAuthRequest.ts │ │ ├── meProgressResponse.ts │ │ ├── lessonResponse.ts │ │ └── courseResponse.ts │ ├── instance.ts │ └── hooks │ │ ├── useLogout.ts │ │ ├── useGetMe.ts │ │ ├── useGetAvailableSsoProviders.ts │ │ ├── useRemoveAllSessions.ts │ │ ├── useGetSessions.ts │ │ ├── useFetchMfaStatus.ts │ │ ├── useFetchSsoStauts.ts │ │ ├── useRevokeSession.ts │ │ ├── useGetPaymentMethods.ts │ │ ├── useUnlinkAccount.ts │ │ ├── useInitPayment.ts │ │ ├── useTelegramConnect.ts │ │ ├── useRegister.ts │ │ ├── useTelegramAuth.ts │ │ ├── useSsoConnect.ts │ │ ├── useLogin.ts │ │ ├── index.ts │ │ └── useVerifyMfa.ts ├── proxy.ts └── styles │ └── globals.css ├── .dockerignore ├── public ├── favicon.ico ├── opengraph.png ├── images │ ├── owl.png │ └── bg-auth.png ├── touch-icons │ ├── 192x192.png │ └── 512x512.png └── payment-logos │ ├── bank-card.svg │ ├── international-card.svg │ ├── crypto.svg │ └── sbp.svg ├── postcss.config.mjs ├── orval.config.ts ├── Dockerfile ├── .gitignore ├── next.config.ts ├── .prettierrc ├── tsconfig.json ├── README.md └── .github └── workflows └── ci.yaml /src/lib/analytics/events/index.ts: -------------------------------------------------------------------------------- 1 | export * from './auth' 2 | -------------------------------------------------------------------------------- /src/lib/analytics/script-providers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './yandex' 2 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .next 3 | *.log 4 | .env 5 | .env.* 6 | .git 7 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/teacoder-team/frontend/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /public/opengraph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/teacoder-team/frontend/HEAD/public/opengraph.png -------------------------------------------------------------------------------- /public/images/owl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/teacoder-team/frontend/HEAD/public/images/owl.png -------------------------------------------------------------------------------- /public/images/bg-auth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/teacoder-team/frontend/HEAD/public/images/bg-auth.png -------------------------------------------------------------------------------- /src/components/account/security/security.tsx: -------------------------------------------------------------------------------- 1 | export function Security() { 2 | return
3 | } 4 | -------------------------------------------------------------------------------- /public/touch-icons/192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/teacoder-team/frontend/HEAD/public/touch-icons/192x192.png -------------------------------------------------------------------------------- /public/touch-icons/512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/teacoder-team/frontend/HEAD/public/touch-icons/512x512.png -------------------------------------------------------------------------------- /src/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export * from './useAuth' 2 | export * from './useCurrent' 3 | export * from './useFingerprint' 4 | -------------------------------------------------------------------------------- /src/lib/analytics/providers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './console' 2 | export * from './metrika' 3 | export * from './posthog' 4 | -------------------------------------------------------------------------------- /src/components/icons/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './sberbank-icon' 2 | export * from './sbp-icon' 3 | export * from './tbank-icon' 4 | export * from './yoomoney-icon' 5 | -------------------------------------------------------------------------------- /src/lib/utils/focus-ring.ts: -------------------------------------------------------------------------------- 1 | export const focusRing = [ 2 | 'outline outline-offset-2 outline-0 focus-visible:outline-2', 3 | 'outline-blue-600 dark:outline-blue-600' 4 | ] 5 | -------------------------------------------------------------------------------- /postcss.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('postcss-load-config').Config} */ 2 | const config = { 3 | plugins: { 4 | tailwindcss: {}, 5 | }, 6 | }; 7 | 8 | export default config; 9 | -------------------------------------------------------------------------------- /src/constants/index.ts: -------------------------------------------------------------------------------- 1 | export * from './app' 2 | export * from './mfa-methods' 3 | export * from './payment-icons' 4 | export * from './routes' 5 | export * from './seo' 6 | export * from './sso-providers' 7 | -------------------------------------------------------------------------------- /src/lib/utils/tw-merge.ts: -------------------------------------------------------------------------------- 1 | import { type ClassValue, clsx } from 'clsx' 2 | import { twMerge } from 'tailwind-merge' 3 | 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)) 6 | } 7 | -------------------------------------------------------------------------------- /src/hooks/useAuth.ts: -------------------------------------------------------------------------------- 1 | import { cookies } from '../lib/cookie' 2 | 3 | export function useAuth() { 4 | const token = cookies.get('token') 5 | const isAuthorized = token !== undefined && token !== '' 6 | 7 | return { isAuthorized } 8 | } 9 | -------------------------------------------------------------------------------- /src/lib/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './focus-ring' 2 | export * from './format-date' 3 | export * from './get-browser-icon' 4 | export * from './get-lesson-label' 5 | export * from './get-media-source' 6 | export * from './translators' 7 | export * from './tw-merge' 8 | -------------------------------------------------------------------------------- /src/app/loading.tsx: -------------------------------------------------------------------------------- 1 | import { EllipsisLoader } from '../components/shared/ellipsis-loader' 2 | 3 | export default function LoadingPage() { 4 | return ( 5 |{description}
11 |Загрузка...
} 30 |16 | Cамые популярные курсы среди пользователей платформы 17 |
18 |18 | Кажется, мы потеряли эту страницу. 19 |
20 |14 | Подписывайся на наш канал! Получай последние новости, общайся с 15 | единомышленниками и будь в курсе самых актуальных событий. 16 |
17 | 18 | 33 |22 | Здесь собраны курсы по веб-разработке, которые помогут вам 23 | освоить самые востребованные технологии и инструменты. 24 |
25 |33 | Чтобы завершить подтверждение почты, нажми на кнопку ниже. 34 |
35 | 44 |30 | {course.shortDescription} 31 |
32 |37 | {course.fullDescription} 38 |
39 |42 | {course.shortDescription} 43 |
44 |27 | {isCurrentSession && ( 28 | 29 | 30 | 31 | 32 | 33 | 34 | Текущее устройство 35 | 36 | • 37 | 38 | )} 39 | {session.city}, {session.country} 40 | {!isCurrentSession && ( 41 | <> • {formatDate(session.createdAt)}> 42 | )} 43 |
44 |43 | Завершите сеанс, чтобы выйти из аккаунта на 44 | этом устройстве. 45 |
46 |50 | Скачайте готовый код или смотрите курс на YouTube 51 |
52 |70 | Форматы: JPEG, PNG, WEBP, GIF. Макс. размер: 10 МБ. 71 |
72 |,
19 | title: 'Практика с кодом',
20 | description:
21 | 'Все курсы включают видеоуроки и реальные примеры кода. Ты сможешь не только изучать теорию, но и сразу применять её на практике.'
22 | }
23 | ]
24 |
25 | return (
26 | 33 | Получи доступ к удобным курсам по программированию, 34 | отслеживай свой прогресс и практикуйся с реальными 35 | примерами кода 36 |
37 |52 | {reason.description} 53 |
54 |54 | Ежемесячно плата списывается автоматически. 55 | Автопродление можно отключить в любой момент. 56 |
57 |58 | {isCompleted 59 | ? 'Вы завершили этот урок!' 60 | : 'Вы готовы завершить этот урок?'} 61 |
62 |63 | {isCompleted 64 | ? 'Отличная работа! Вы можете посмотреть свою статистику в личном кабинете.' 65 | : 'Не забудьте завершить урок, когда будете готовы.'} 66 |
67 |29 | {totalLessons} {lessonsTranslator(totalLessons)} •{' '} 30 | {completedCount} выполнено 31 |
32 | )} 33 |76 | {lesson.description} 77 |
78 | )} 79 |