From 2582f297ea4f05355d343476d224fbc25f6b42d6 Mon Sep 17 00:00:00 2001 From: Vy Ngo Chi Date: Mon, 24 Aug 2026 17:55:14 +0700 Subject: [PATCH 1/3] feat: implement SEO configurations, site maps, robots, and authentication middleware for lms and sale apps --- .github/workflows/ci-cd.yml | 3 + apps/lms/app/(home)/page.tsx | 2 + apps/lms/app/layout.tsx | 2 + apps/lms/app/robots.ts | 14 +++++ apps/lms/app/sitemap.ts | 6 ++ apps/lms/configs/seo.ts | 30 ++++++++++ apps/lms/proxy.ts | 2 +- apps/sale/app/(guest)/about-us/page.tsx | 1 + .../sale/app/(guest)/favorite-tutors/page.tsx | 1 + apps/sale/app/(guest)/page.tsx | 1 + apps/sale/app/(guest)/tutor-guide/page.tsx | 1 + apps/sale/app/(guest)/tutors/page.tsx | 1 + apps/sale/app/layout.tsx | 2 + apps/sale/app/robots.ts | 14 +++++ apps/sale/app/sitemap.ts | 8 +++ apps/sale/configs/seo.ts | 38 +++++++++++++ package-lock.json | 56 +++++++++++++++---- 17 files changed, 170 insertions(+), 12 deletions(-) create mode 100644 apps/lms/app/robots.ts create mode 100644 apps/lms/app/sitemap.ts create mode 100644 apps/lms/configs/seo.ts create mode 100644 apps/sale/app/robots.ts create mode 100644 apps/sale/app/sitemap.ts create mode 100644 apps/sale/configs/seo.ts diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index bad7746..86f4d82 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -20,6 +20,9 @@ jobs: node-version: '20' cache: 'npm' + - name: Use project npm version + run: npm install --global npm@11.6.1 + - name: Install dependencies run: npm ci diff --git a/apps/lms/app/(home)/page.tsx b/apps/lms/app/(home)/page.tsx index 4df5e77..c5b1c7a 100644 --- a/apps/lms/app/(home)/page.tsx +++ b/apps/lms/app/(home)/page.tsx @@ -10,6 +10,8 @@ export const metadata: Metadata = { title: "BeeWise LMS | Hệ Thống Quản Lý Học Tập Thông Minh", description: "Không gian làm việc và học tập của Gia sư và Học viên. Số hóa lịch trình, lưu trữ tài liệu và tối ưu hóa hiệu quả dạy & học trên BeeWise LMS.", + alternates: { canonical: "/" }, + robots: { index: true, follow: true }, }; export default function LmsHomePage() { diff --git a/apps/lms/app/layout.tsx b/apps/lms/app/layout.tsx index 3e16022..200a7fd 100644 --- a/apps/lms/app/layout.tsx +++ b/apps/lms/app/layout.tsx @@ -3,8 +3,10 @@ import "@workspace/ui/globals.css"; import { Metadata } from "next"; import { googleSans, nunito } from "@workspace/core/configs/fonts"; import { TooltipProvider } from "@workspace/ui/components/ui/tooltip"; +import { lmsSeoConfig } from "@/configs/seo"; export const metadata: Metadata = { + metadataBase: new URL(lmsSeoConfig.siteUrl), title: "BeeWise LMS | Hệ Thống Quản Lý Học Tập Thông Minh", }; diff --git a/apps/lms/app/robots.ts b/apps/lms/app/robots.ts new file mode 100644 index 0000000..b6db78a --- /dev/null +++ b/apps/lms/app/robots.ts @@ -0,0 +1,14 @@ +import type { MetadataRoute } from "next"; +import { getLmsUrl, lmsSeoConfig } from "@/configs/seo"; + +export default function robots(): MetadataRoute.Robots { + return { + rules: { + userAgent: "*", + allow: ["/", "/login"], + disallow: "/lms/", + }, + sitemap: getLmsUrl("/sitemap.xml"), + host: lmsSeoConfig.siteUrl, + }; +} diff --git a/apps/lms/app/sitemap.ts b/apps/lms/app/sitemap.ts new file mode 100644 index 0000000..78beaa2 --- /dev/null +++ b/apps/lms/app/sitemap.ts @@ -0,0 +1,6 @@ +import type { MetadataRoute } from "next"; +import { getLmsUrl } from "@/configs/seo"; + +export default function sitemap(): MetadataRoute.Sitemap { + return [{ url: getLmsUrl("/") }]; +} diff --git a/apps/lms/configs/seo.ts b/apps/lms/configs/seo.ts new file mode 100644 index 0000000..57b708b --- /dev/null +++ b/apps/lms/configs/seo.ts @@ -0,0 +1,30 @@ +const DEFAULT_LMS_SITE_URL = "https://superlms.beewise.vn"; + +function resolveSiteUrl(value: string | undefined, fallback: string): string { + if (!value) { + return fallback; + } + + try { + const url = new URL(value); + + if (url.protocol !== "https:" && url.protocol !== "http:") { + return fallback; + } + + return url.origin; + } catch { + return fallback; + } +} + +export const lmsSeoConfig = { + siteUrl: resolveSiteUrl( + process.env.NEXT_PUBLIC_SITE_URL, + DEFAULT_LMS_SITE_URL, + ), +} as const; + +export function getLmsUrl(pathname: string): string { + return new URL(pathname, `${lmsSeoConfig.siteUrl}/`).toString(); +} diff --git a/apps/lms/proxy.ts b/apps/lms/proxy.ts index 9ddc43a..e428333 100644 --- a/apps/lms/proxy.ts +++ b/apps/lms/proxy.ts @@ -1,7 +1,7 @@ import { NextResponse } from "next/server"; import type { NextRequest } from "next/server"; -const publicPaths = ["/", "/login"]; +const publicPaths = ["/", "/login", "/robots.txt", "/sitemap.xml"]; export function proxy(request: NextRequest) { const { pathname } = request.nextUrl; diff --git a/apps/sale/app/(guest)/about-us/page.tsx b/apps/sale/app/(guest)/about-us/page.tsx index e322214..e1ee8a4 100644 --- a/apps/sale/app/(guest)/about-us/page.tsx +++ b/apps/sale/app/(guest)/about-us/page.tsx @@ -27,6 +27,7 @@ export const metadata: Metadata = { locale: "vi_VN", siteName: "BeeWise", }, + alternates: { canonical: "/about-us" }, }; export default function AboutPage() { diff --git a/apps/sale/app/(guest)/favorite-tutors/page.tsx b/apps/sale/app/(guest)/favorite-tutors/page.tsx index 4599a0b..1fdf4b5 100644 --- a/apps/sale/app/(guest)/favorite-tutors/page.tsx +++ b/apps/sale/app/(guest)/favorite-tutors/page.tsx @@ -4,6 +4,7 @@ import { FavoriteTutorsPage } from "../../../features/favorite-tutors/components export const metadata: Metadata = { title: "Gia sư yêu thích | BeeWise", description: "Danh sách các gia sư bạn đã lưu lại trên hệ thống BeeWise.", + robots: { index: false, follow: false }, }; import { Header } from "@workspace/ui/components/layout/Header"; diff --git a/apps/sale/app/(guest)/page.tsx b/apps/sale/app/(guest)/page.tsx index f9fa728..8ab7beb 100644 --- a/apps/sale/app/(guest)/page.tsx +++ b/apps/sale/app/(guest)/page.tsx @@ -39,6 +39,7 @@ export const metadata: Metadata = { description: "Tìm gia sư phù hợp trong 30 giây với AI. Hồ sơ xác thực, cố vấn đồng hành, miễn phí.", }, + alternates: { canonical: "/" }, robots: { index: true, follow: true, diff --git a/apps/sale/app/(guest)/tutor-guide/page.tsx b/apps/sale/app/(guest)/tutor-guide/page.tsx index f09ee37..fd39c6a 100644 --- a/apps/sale/app/(guest)/tutor-guide/page.tsx +++ b/apps/sale/app/(guest)/tutor-guide/page.tsx @@ -23,6 +23,7 @@ export const metadata: Metadata = { "nền tảng gia sư", "BeeWise", ], + alternates: { canonical: "/tutor-guide" }, }; export default function TutorGuidePage() { diff --git a/apps/sale/app/(guest)/tutors/page.tsx b/apps/sale/app/(guest)/tutors/page.tsx index 629c896..267816b 100644 --- a/apps/sale/app/(guest)/tutors/page.tsx +++ b/apps/sale/app/(guest)/tutors/page.tsx @@ -18,6 +18,7 @@ export const metadata: Metadata = { "BeeWise", "tìm gia sư AI", ], + alternates: { canonical: "/tutors" }, }; export default function TutorListPage() { diff --git a/apps/sale/app/layout.tsx b/apps/sale/app/layout.tsx index 17ceea3..4322fba 100644 --- a/apps/sale/app/layout.tsx +++ b/apps/sale/app/layout.tsx @@ -4,8 +4,10 @@ import "@workspace/ui/globals.css"; import { Metadata } from "next"; import { GuestFavoriteModal } from "@/features/favorite-tutors/components/GuestFavoriteModal"; import { NotificationDrawer } from "@/features/notifications/components/NotificationDrawer"; +import { saleSeoConfig } from "@/configs/seo"; export const metadata: Metadata = { + metadataBase: new URL(saleSeoConfig.siteUrl), title: "Cộng đồng gia sư", }; diff --git a/apps/sale/app/robots.ts b/apps/sale/app/robots.ts new file mode 100644 index 0000000..41aee19 --- /dev/null +++ b/apps/sale/app/robots.ts @@ -0,0 +1,14 @@ +import type { MetadataRoute } from "next"; +import { getSaleUrl, saleSeoConfig } from "@/configs/seo"; + +export default function robots(): MetadataRoute.Robots { + return { + rules: { + userAgent: "*", + allow: "/", + disallow: [...saleSeoConfig.privateRoutes], + }, + sitemap: getSaleUrl("/sitemap.xml"), + host: saleSeoConfig.siteUrl, + }; +} diff --git a/apps/sale/app/sitemap.ts b/apps/sale/app/sitemap.ts new file mode 100644 index 0000000..120c326 --- /dev/null +++ b/apps/sale/app/sitemap.ts @@ -0,0 +1,8 @@ +import type { MetadataRoute } from "next"; +import { getSaleUrl, saleSeoConfig } from "@/configs/seo"; + +export default function sitemap(): MetadataRoute.Sitemap { + return saleSeoConfig.indexableRoutes.map((route) => ({ + url: getSaleUrl(route), + })); +} diff --git a/apps/sale/configs/seo.ts b/apps/sale/configs/seo.ts new file mode 100644 index 0000000..f43abe2 --- /dev/null +++ b/apps/sale/configs/seo.ts @@ -0,0 +1,38 @@ +const DEFAULT_SALE_SITE_URL = "https://beewise.vn"; + +function resolveSiteUrl(value: string | undefined, fallback: string): string { + if (!value) { + return fallback; + } + + try { + const url = new URL(value); + + if (url.protocol !== "https:" && url.protocol !== "http:") { + return fallback; + } + + return url.origin; + } catch { + return fallback; + } +} + +export const saleSeoConfig = { + siteUrl: resolveSiteUrl( + process.env.NEXT_PUBLIC_SITE_URL, + DEFAULT_SALE_SITE_URL, + ), + indexableRoutes: ["/", "/tutors", "/tutor-guide", "/about-us"], + privateRoutes: [ + "/learner/", + "/tutor/", + "/community/applications", + "/community/my-posts", + "/dev/", + ], +} as const; + +export function getSaleUrl(pathname: string): string { + return new URL(pathname, `${saleSeoConfig.siteUrl}/`).toString(); +} diff --git a/package-lock.json b/package-lock.json index b96de76..3ad564e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -369,17 +369,6 @@ "node": ">=6.9.0" } }, - "node_modules/@emnapi/wasi-threads": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.3.tgz", - "integrity": "sha512-ELEBe8PsLvvJ6QMr0zLt8ffvOHW/dc1m3CEzNMg7aJUv3bMaoDtw2TXyDAwkYBuroxxuHEwhRTLJSe5sya547g==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, "node_modules/@eslint-community/eslint-utils": { "version": "4.9.1", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", @@ -3307,6 +3296,51 @@ "node": ">=14.0.0" } }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads": { + "version": "1.2.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": { + "version": "0.10.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib": { + "version": "2.8.1", + "dev": true, + "inBundle": true, + "license": "0BSD", + "optional": true + }, "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.2.tgz", From 848e3b8f026c1c8ebe3036039a94b7574de26c9c Mon Sep 17 00:00:00 2001 From: Vy Ngo Chi Date: Wed, 26 Aug 2026 16:06:04 +0700 Subject: [PATCH 2/3] feat: implement tutor profile editor system and add messages screen UI --- apps/sale/app/tutor/profile/edit/loading.tsx | 5 + .../messages/components/ChatSidebar.tsx | 2 +- .../messages/components/MessagesScreen.tsx | 7 +- .../components/TutorApprovedPreview.tsx | 6 +- .../components/tutor-approved.ui.tsx | 139 ++---------- .../components/AvailabilityListField.tsx | 68 ++++++ .../components/EditableProfileBlock.tsx | 39 ++++ .../components/ProfileBlockDialog.tsx | 80 +++++++ .../components/ProfileEditModalRouter.tsx | 52 +++++ .../components/ProfileEditorSkeleton.tsx | 31 +++ .../components/ProfileEditorToolbar.tsx | 37 ++++ .../components/ProfileField.tsx | 113 ++++++++++ .../components/RepeaterPrimitives.tsx | 86 ++++++++ .../components/SimpleListField.tsx | 75 +++++++ .../components/TeachingMethodListField.tsx | 59 +++++ .../components/TutorEvidenceEditorPreview.tsx | 45 ++++ .../components/TutorProfileEditorScreen.tsx | 77 +++++++ .../components/TutorProfileSidebarPreview.tsx | 21 ++ .../components/TutorVideoEditorPreview.tsx | 19 ++ .../modals/AcademicProfileEditDialog.tsx | 84 ++++++++ .../components/modals/BasicInfoEditDialog.tsx | 135 ++++++++++++ .../components/modals/EvidenceEditDialog.tsx | 203 ++++++++++++++++++ .../modals/ExperienceEditDialog.tsx | 95 ++++++++ .../modals/IntroductionEditDialog.tsx | 17 ++ .../modals/TeachingMethodsEditDialog.tsx | 17 ++ .../components/modals/VideoEditDialog.tsx | 108 ++++++++++ .../constants/profile-editor.fixture.ts | 44 ++++ .../constants/profile-editor.options.ts | 21 ++ .../hooks/useTutorProfileInlineEditor.ts | 68 ++++++ .../features/tutor-profile-editor/index.ts | 2 + .../schemas/profile-editor.schema.ts | 84 ++++++++ .../services/profile-editor.service.ts | 25 +++ .../types/profile-editor.types.ts | 12 ++ .../utils/file-preview.ts | 21 ++ .../utils/profile-editor.mapper.ts | 47 ++++ .../tutor-profile/components/TutorHero.tsx | 8 +- .../components/TutorOwnProfileScreen.tsx | 91 ++++++++ .../tutor-profile/types/mockTutorProfile.ts | 15 +- .../features/auth/components/AuthLayout.tsx | 16 -- packages/core/configs/navigation.ts | 8 +- packages/ui/components/layout/Header.tsx | 17 +- 41 files changed, 1941 insertions(+), 158 deletions(-) create mode 100644 apps/sale/app/tutor/profile/edit/loading.tsx create mode 100644 apps/sale/features/tutor-profile-editor/components/AvailabilityListField.tsx create mode 100644 apps/sale/features/tutor-profile-editor/components/EditableProfileBlock.tsx create mode 100644 apps/sale/features/tutor-profile-editor/components/ProfileBlockDialog.tsx create mode 100644 apps/sale/features/tutor-profile-editor/components/ProfileEditModalRouter.tsx create mode 100644 apps/sale/features/tutor-profile-editor/components/ProfileEditorSkeleton.tsx create mode 100644 apps/sale/features/tutor-profile-editor/components/ProfileEditorToolbar.tsx create mode 100644 apps/sale/features/tutor-profile-editor/components/ProfileField.tsx create mode 100644 apps/sale/features/tutor-profile-editor/components/RepeaterPrimitives.tsx create mode 100644 apps/sale/features/tutor-profile-editor/components/SimpleListField.tsx create mode 100644 apps/sale/features/tutor-profile-editor/components/TeachingMethodListField.tsx create mode 100644 apps/sale/features/tutor-profile-editor/components/TutorEvidenceEditorPreview.tsx create mode 100644 apps/sale/features/tutor-profile-editor/components/TutorProfileEditorScreen.tsx create mode 100644 apps/sale/features/tutor-profile-editor/components/TutorProfileSidebarPreview.tsx create mode 100644 apps/sale/features/tutor-profile-editor/components/TutorVideoEditorPreview.tsx create mode 100644 apps/sale/features/tutor-profile-editor/components/modals/AcademicProfileEditDialog.tsx create mode 100644 apps/sale/features/tutor-profile-editor/components/modals/BasicInfoEditDialog.tsx create mode 100644 apps/sale/features/tutor-profile-editor/components/modals/EvidenceEditDialog.tsx create mode 100644 apps/sale/features/tutor-profile-editor/components/modals/ExperienceEditDialog.tsx create mode 100644 apps/sale/features/tutor-profile-editor/components/modals/IntroductionEditDialog.tsx create mode 100644 apps/sale/features/tutor-profile-editor/components/modals/TeachingMethodsEditDialog.tsx create mode 100644 apps/sale/features/tutor-profile-editor/components/modals/VideoEditDialog.tsx create mode 100644 apps/sale/features/tutor-profile-editor/constants/profile-editor.fixture.ts create mode 100644 apps/sale/features/tutor-profile-editor/constants/profile-editor.options.ts create mode 100644 apps/sale/features/tutor-profile-editor/hooks/useTutorProfileInlineEditor.ts create mode 100644 apps/sale/features/tutor-profile-editor/index.ts create mode 100644 apps/sale/features/tutor-profile-editor/schemas/profile-editor.schema.ts create mode 100644 apps/sale/features/tutor-profile-editor/services/profile-editor.service.ts create mode 100644 apps/sale/features/tutor-profile-editor/types/profile-editor.types.ts create mode 100644 apps/sale/features/tutor-profile-editor/utils/file-preview.ts create mode 100644 apps/sale/features/tutor-profile-editor/utils/profile-editor.mapper.ts create mode 100644 apps/sale/features/tutor-profile/components/TutorOwnProfileScreen.tsx diff --git a/apps/sale/app/tutor/profile/edit/loading.tsx b/apps/sale/app/tutor/profile/edit/loading.tsx new file mode 100644 index 0000000..b475b4b --- /dev/null +++ b/apps/sale/app/tutor/profile/edit/loading.tsx @@ -0,0 +1,5 @@ +import { ProfileEditorSkeleton } from "@/features/tutor-profile-editor"; + +export default function Loading() { + return ; +} diff --git a/apps/sale/features/messages/components/ChatSidebar.tsx b/apps/sale/features/messages/components/ChatSidebar.tsx index 640796e..1c3593d 100644 --- a/apps/sale/features/messages/components/ChatSidebar.tsx +++ b/apps/sale/features/messages/components/ChatSidebar.tsx @@ -126,7 +126,7 @@ export function ChatSidebar() { className="text-sm tracking-tight text-[#280f91]" style={{ fontFamily: "var(--font-nunito-family)", fontWeight: 800 }} > - CỘNG ĐỒNG GIA SƯ + CỘNG ĐỒNG GIA SƯ BEEWISE diff --git a/apps/sale/features/messages/components/MessagesScreen.tsx b/apps/sale/features/messages/components/MessagesScreen.tsx index 8db88fb..a494977 100644 --- a/apps/sale/features/messages/components/MessagesScreen.tsx +++ b/apps/sale/features/messages/components/MessagesScreen.tsx @@ -22,9 +22,12 @@ export function MessagesScreen() { - CỘNG ĐỒNG GIA SƯ + CỘNG ĐỒNG GIA SƯ BEEWISE

diff --git a/apps/sale/features/tutor-approved/components/TutorApprovedPreview.tsx b/apps/sale/features/tutor-approved/components/TutorApprovedPreview.tsx index c977977..13b34c3 100644 --- a/apps/sale/features/tutor-approved/components/TutorApprovedPreview.tsx +++ b/apps/sale/features/tutor-approved/components/TutorApprovedPreview.tsx @@ -3,7 +3,7 @@ import { useRouter } from "next/navigation"; import { TutorApprovedProvider } from "./TutorApprovedProvider"; import { TutorApprovedScreenView, TutorApprovedShell } from "./tutor-approved.ui"; -import { resolveTutorApprovedScenario, parseTutorApprovedScenario } from "../schemas/tutor-approved.resolver"; +import { parseTutorApprovedScenario } from "../schemas/tutor-approved.resolver"; import { tutorApprovedScenarios, type TutorApprovedScenario, type TutorApprovedScreen } from "../types"; const previewUser = { @@ -31,6 +31,7 @@ function scenarioScreen(scenario: TutorApprovedScenario): TutorApprovedScreen { export function TutorApprovedPreview({ scenario, capture }: { scenario?: string | null; capture: boolean }) { const parsed = parseTutorApprovedScenario(scenario); + const screen = scenarioScreen(parsed); const router = useRouter(); const navigate = (next: TutorApprovedScenario, nextCapture = capture) => { const params = new URLSearchParams({ scenario: next }); @@ -40,11 +41,12 @@ export function TutorApprovedPreview({ scenario, capture }: { scenario?: string return ( PREVIEW : null} > - + ); diff --git a/apps/sale/features/tutor-approved/components/tutor-approved.ui.tsx b/apps/sale/features/tutor-approved/components/tutor-approved.ui.tsx index 1cd578a..c34d618 100644 --- a/apps/sale/features/tutor-approved/components/tutor-approved.ui.tsx +++ b/apps/sale/features/tutor-approved/components/tutor-approved.ui.tsx @@ -26,6 +26,8 @@ import { TUTOR_LMS_URL } from "@workspace/core/constants/tutor-links"; import { useTutorApproved } from "./TutorApprovedProvider"; import type { TutorApprovedScreen } from "../types"; import { ChatSummary, MessagesScreen, ChatRoomScreen } from "../../messages"; +import { TutorProfileEditorScreen } from "../../tutor-profile-editor"; +import { TutorOwnProfileScreen } from "../../tutor-profile/components/TutorOwnProfileScreen"; const card = "rounded-2xl border border-[#dce7f7] bg-white p-5 shadow-[0_12px_32px_rgba(40,15,145,0.07)]"; @@ -46,6 +48,15 @@ export function TutorApprovedShell({ screen?: TutorApprovedScreen; }) { const isChat = screen === "messages" || screen === "chat-room"; + const isProfileEdit = screen === "profile-edit"; + + if (isProfileEdit) { + return ( +
+ {children} +
+ ); + } if (isChat) { return ( @@ -84,8 +95,8 @@ export function TutorApprovedScreenView({ screen?: TutorApprovedScreen; chatRoomId?: string; }) { - if (screen === "profile" || screen === "profile-edit") - return ; + if (screen === "profile-edit") return ; + if (screen === "profile") return ; if (screen === "messages") return ; if (screen === "chat-room") return ; if (screen === "notifications") return ; @@ -476,130 +487,6 @@ function RecentActivity() { ); } -function ProfileScreen({ edit }: { edit: boolean }) { - const { state, dispatch } = useTutorApproved(); - const p = edit ? state.draftProfile : state.profile; - const fields: - | [[keyof typeof p, string, boolean]] - | Array<[keyof typeof p, string, boolean]> = [ - ["title", "Tiêu đề hồ sơ", true], - ["introduction", "Giới thiệu ngắn", true], - ["description", "Mô tả", true], - ["teachingMethod", "Phương pháp giảng dạy", false], - ["experience", "Kinh nghiệm", false], - ["rate", "Học phí dự kiến", true], - ]; - return ( -
-
-

Hồ sơ gia sư

-

- {edit ? "Chỉnh sửa hồ sơ" : "Hồ sơ của tôi"} -

-

- Thông tin ngân hàng và giấy tờ xác thực không xuất hiện trong hồ sơ - công khai. -

-
- {state.profileSubmitted && ( -
- Thay đổi đã được gửi. Hồ sơ công khai hiện tại vẫn được giữ cho đến - khi Consultant phê duyệt nội dung mới. -
- )} -
-
-
- MA -
-
-

{p.fullName}

- - Đã xác thực - -
-
- {edit ? ( -
{ - e.preventDefault(); - dispatch({ type: "submit-profile" }); - }} - className="space-y-4" - > - {fields.map(([field, label, review]) => ( -