diff --git a/package-lock.json b/package-lock.json index 0fb2f56..3a96594 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,6 +23,7 @@ "lucide-react": "^0.561.0", "react": "^19.2.0", "react-dom": "^19.2.0", + "react-is": "^19.2.5", "react-router-dom": "^7.10.1", "recharts": "^3.6.0", "sonner": "^2.0.7", @@ -5315,11 +5316,10 @@ } }, "node_modules/react-is": { - "version": "19.2.3", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.3.tgz", - "integrity": "sha512-qJNJfu81ByyabuG7hPFEbXqNcWSU3+eVus+KJs+0ncpGfMyYdvSmxiJxbWR65lYi1I+/0HBcliO029gc4F+PnA==", - "license": "MIT", - "peer": true + "version": "19.2.5", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.5.tgz", + "integrity": "sha512-Dn0t8IQhCmeIT3wu+Apm1/YVsJXsGWi6k4sPdnBIdqMVtHtv0IGi6dcpNpNkNac0zB2uUAqNX3MHzN8c+z2rwQ==", + "license": "MIT" }, "node_modules/react-redux": { "version": "9.2.0", diff --git a/package.json b/package.json index eba2940..57f998e 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "lucide-react": "^0.561.0", "react": "^19.2.0", "react-dom": "^19.2.0", + "react-is": "^19.2.5", "react-router-dom": "^7.10.1", "recharts": "^3.6.0", "sonner": "^2.0.7", diff --git a/src/app/AppRoutes.tsx b/src/app/AppRoutes.tsx index 5c75232..7502414 100644 --- a/src/app/AppRoutes.tsx +++ b/src/app/AppRoutes.tsx @@ -1,52 +1,59 @@ -import { Navigate, Route, Routes } from "react-router-dom" -import { AppLayout } from "../layouts/AppLayout" -import { DashboardPage } from "../pages/DashboardPage" -import { AnalyticsPage } from "../pages/analytics/AnalyticsPage" -import { ContentManagementLayout } from "../pages/content-management/ContentManagementLayout" -import { CourseCategoryPage } from "../pages/content-management/CourseCategoryPage" -import { AllCoursesPage } from "../pages/content-management/AllCoursesPage" -import { CourseFlowBuilderPage } from "../pages/content-management/CourseFlowBuilderPage" -import { ContentOverviewPage } from "../pages/content-management/ContentOverviewPage" -import { CoursesPage } from "../pages/content-management/CoursesPage" -import { PracticeQuestionsPage } from "../pages/content-management/PracticeQuestionsPage" -import { AddNewPracticePage } from "../pages/content-management/AddNewPracticePage" -import { SubModulesPage } from "../pages/content-management/SubCoursesPage" -import { SubModuleContentPage } from "../pages/content-management/SubCourseContentPage" -import { SpeakingPage } from "../pages/content-management/SpeakingPage" -import { AddVideoPage } from "../pages/content-management/AddVideoPage" -import { AddPracticePage } from "../pages/content-management/AddPracticePage" -import { NotFoundPage } from "../pages/NotFoundPage" -import { NotificationsPage } from "../pages/notifications/NotificationsPage" -import { CreateNotificationPage } from "../pages/notifications/CreateNotificationPage" -import { UserDetailPage } from "../pages/user-management/UserDetailPage" -import { UserManagementLayout } from "../pages/user-management/UserManagementLayout" -import { UsersListPage } from "../pages/user-management/UsersListPage" -import { UserManagementDashboard } from "../pages/user-management/UserManagementDashboard" -import { UserGroupsPage } from "../pages/user-management/UserGroupsPage" -import { DeletionRequestsPage } from "../pages/user-management/DeletionRequestsPage" -import { RoleManagementLayout } from "../pages/role-management/RoleManagementLayout" -import { RolesListPage } from "../pages/role-management/RolesListPage" -import { AddRolePage } from "../pages/role-management/AddRolePage" -import { PracticeDetailsPage } from "../pages/content-management/PracticeDetailsPage" -import { PracticeMembersPage } from "../pages/content-management/PracticeMembersPage" -import { QuestionsPage } from "../pages/content-management/QuestionsPage" -import { AddQuestionPage } from "../pages/content-management/AddQuestionPage" -import { HumanLanguagePage } from "../pages/content-management/HumanLanguagePage" -import { HumanLanguageSubModulePage } from "../pages/content-management/HumanLanguageSubModulePage" -import { UserLogPage } from "../pages/user-log/UserLogPage" -import { IssuesPage } from "../pages/issues/IssuesPage" -import { ProfilePage } from "../pages/ProfilePage" -import { SettingsPage } from "../pages/SettingsPage" -import { TeamManagementPage } from "../pages/team/TeamManagementPage" -import { AddTeamMemberPage } from "../pages/team/AddTeamMemberPage" -import { TeamMemberDetailPage } from "../pages/team/TeamMemberDetailPage" -import { LoginPage } from "../pages/auth/LoginPage" -import { ForgotPasswordPage } from "../pages/auth/ForgotPasswordPage" -import { VerificationPage } from "../pages/auth/VerificationPage" -import { AboutPage } from "../pages/AboutPage" -import { TermsPage } from "../pages/TermsPage" -import { PrivacyPage } from "../pages/PrivacyPage" -import { AccountDeletionPage } from "../pages/AccountDeletionPage" +import { Navigate, Route, Routes } from "react-router-dom"; +import { AppLayout } from "../layouts/AppLayout"; +import { DashboardPage } from "../pages/DashboardPage"; +import { AnalyticsPage } from "../pages/analytics/AnalyticsPage"; +import { ContentManagementLayout } from "../pages/content-management/ContentManagementLayout"; +import { CourseCategoryPage } from "../pages/content-management/CourseCategoryPage"; +import { AllCoursesPage } from "../pages/content-management/AllCoursesPage"; +import { CourseFlowBuilderPage } from "../pages/content-management/CourseFlowBuilderPage"; +import { ContentOverviewPage } from "../pages/content-management/ContentOverviewPage"; +import { CoursesPage } from "../pages/content-management/CoursesPage"; +import { PracticeQuestionsPage } from "../pages/content-management/PracticeQuestionsPage"; +import { AddNewPracticePage } from "../pages/content-management/AddNewPracticePage"; +import { SubModulesPage } from "../pages/content-management/SubCoursesPage"; +import { SubModuleContentPage } from "../pages/content-management/SubCourseContentPage"; +import { SpeakingPage } from "../pages/content-management/SpeakingPage"; +import { AddVideoPage } from "../pages/content-management/AddVideoPage"; +import { AddPracticePage } from "../pages/content-management/AddPracticePage"; +import { NewContentPage } from "../pages/content-management/NewContentPage"; +import { LearnEnglishPage } from "../pages/content-management/LearnEnglishPage"; +import { ProgramCoursesPage } from "../pages/content-management/ProgramCoursesPage"; +import { CourseDetailPage } from "../pages/content-management/CourseDetailPage"; +import { ModuleDetailPage } from "../pages/content-management/ModuleDetailPage"; +import { AddVideoFlow } from "../pages/content-management/AddVideoFlow"; +import { AddPracticeFlow } from "../pages/content-management/AddPracticeFlow"; +import { NotFoundPage } from "../pages/NotFoundPage"; +import { NotificationsPage } from "../pages/notifications/NotificationsPage"; +import { CreateNotificationPage } from "../pages/notifications/CreateNotificationPage"; +import { UserDetailPage } from "../pages/user-management/UserDetailPage"; +import { UserManagementLayout } from "../pages/user-management/UserManagementLayout"; +import { UsersListPage } from "../pages/user-management/UsersListPage"; +import { UserManagementDashboard } from "../pages/user-management/UserManagementDashboard"; +import { UserGroupsPage } from "../pages/user-management/UserGroupsPage"; +import { DeletionRequestsPage } from "../pages/user-management/DeletionRequestsPage"; +import { RoleManagementLayout } from "../pages/role-management/RoleManagementLayout"; +import { RolesListPage } from "../pages/role-management/RolesListPage"; +import { AddRolePage } from "../pages/role-management/AddRolePage"; +import { PracticeDetailsPage } from "../pages/content-management/PracticeDetailsPage"; +import { PracticeMembersPage } from "../pages/content-management/PracticeMembersPage"; +import { QuestionsPage } from "../pages/content-management/QuestionsPage"; +import { AddQuestionPage } from "../pages/content-management/AddQuestionPage"; +import { HumanLanguagePage } from "../pages/content-management/HumanLanguagePage"; +import { HumanLanguageSubModulePage } from "../pages/content-management/HumanLanguageSubModulePage"; +import { UserLogPage } from "../pages/user-log/UserLogPage"; +import { IssuesPage } from "../pages/issues/IssuesPage"; +import { ProfilePage } from "../pages/ProfilePage"; +import { SettingsPage } from "../pages/SettingsPage"; +import { TeamManagementPage } from "../pages/team/TeamManagementPage"; +import { AddTeamMemberPage } from "../pages/team/AddTeamMemberPage"; +import { TeamMemberDetailPage } from "../pages/team/TeamMemberDetailPage"; +import { LoginPage } from "../pages/auth/LoginPage"; +import { ForgotPasswordPage } from "../pages/auth/ForgotPasswordPage"; +import { VerificationPage } from "../pages/auth/VerificationPage"; +import { AboutPage } from "../pages/AboutPage"; +import { TermsPage } from "../pages/TermsPage"; +import { PrivacyPage } from "../pages/PrivacyPage"; +import { AccountDeletionPage } from "../pages/AccountDeletionPage"; export function AppRoutes() { return ( @@ -91,19 +98,52 @@ export function AppRoutes() { path="human-language/:categoryId/:courseId/sub-module/:subModuleId" element={} /> - } /> - } /> + } + /> + } + /> {/* Course → Sub-module → Lesson/Practice */} - } /> - } /> - } /> - } /> + } + /> + } + /> + } + /> + } + /> {/* Legacy aliases */} - } /> - } /> - } /> - } /> - } /> + } + /> + } + /> + } + /> + } + /> + } + /> } /> } /> } /> @@ -113,8 +153,37 @@ export function AppRoutes() { } /> + } /> + } + /> + } + /> + } + /> + } + /> + } + /> + } + /> + } /> - } /> + } + /> } /> } /> } /> @@ -128,7 +197,5 @@ export function AppRoutes() { } /> - ) + ); } - - diff --git a/src/assets/icons/upload.png b/src/assets/icons/upload.png new file mode 100644 index 0000000..44342e3 Binary files /dev/null and b/src/assets/icons/upload.png differ diff --git a/src/components/sidebar/Sidebar.tsx b/src/components/sidebar/Sidebar.tsx index 10bd6da..ce361c2 100644 --- a/src/components/sidebar/Sidebar.tsx +++ b/src/components/sidebar/Sidebar.tsx @@ -13,57 +13,65 @@ import { Users, Users2, X, -} from "lucide-react" -import { type ComponentType, useEffect, useState } from "react" -import { NavLink } from "react-router-dom" -import { cn } from "../../lib/utils" -import { BrandLogo } from "../brand/BrandLogo" -import { getUnreadCount } from "../../api/notifications.api" +} from "lucide-react"; +import { type ComponentType, useEffect, useState } from "react"; +import { NavLink } from "react-router-dom"; +import { cn } from "../../lib/utils"; +import { BrandLogo } from "../brand/BrandLogo"; +import { getUnreadCount } from "../../api/notifications.api"; type NavItem = { - label: string - to: string - icon: ComponentType<{ className?: string }> -} + label: string; + to: string; + icon: ComponentType<{ className?: string }>; +}; const navItems: NavItem[] = [ { label: "Dashboard", to: "/dashboard", icon: LayoutDashboard }, { label: "User Management", to: "/users", icon: Users }, { label: "Role Management", to: "/roles", icon: Shield }, { label: "Content Management", to: "/content", icon: BookOpen }, + { label: "New Content", to: "/new-content", icon: BookOpen }, + { label: "Notifications", to: "/notifications", icon: Bell }, { label: "User Log", to: "/user-log", icon: ClipboardList }, { label: "Issue Reports", to: "/issues", icon: CircleAlert }, { label: "Analytics", to: "/analytics", icon: BarChart3 }, { label: "Team Management", to: "/team", icon: Users2 }, { label: "Profile", to: "/profile", icon: UserCircle2 }, -] +]; type SidebarProps = { - isOpen: boolean - isCollapsed: boolean - onToggleCollapse: () => void - onClose: () => void -} + isOpen: boolean; + isCollapsed: boolean; + onToggleCollapse: () => void; + onClose: () => void; +}; -export function Sidebar({ isOpen, isCollapsed, onToggleCollapse, onClose }: SidebarProps) { - const [unreadCount, setUnreadCount] = useState(0) +export function Sidebar({ + isOpen, + isCollapsed, + onToggleCollapse, + onClose, +}: SidebarProps) { + const [unreadCount, setUnreadCount] = useState(0); useEffect(() => { const fetchUnread = async () => { try { - const res = await getUnreadCount() - setUnreadCount(res.data.unread) + const res = await getUnreadCount(); + setUnreadCount(res.data.unread); } catch { // silently fail } - } + }; - fetchUnread() + fetchUnread(); - window.addEventListener("notifications-updated", fetchUnread) - return () => window.removeEventListener("notifications-updated", fetchUnread) - }, []) + window.addEventListener("notifications-updated", fetchUnread); + return () => + window.removeEventListener("notifications-updated", fetchUnread); + }, []); return ( <> @@ -86,7 +94,12 @@ export function Sidebar({ isOpen, isCollapsed, onToggleCollapse, onClose }: Side isOpen ? "translate-x-0" : "-translate-x-full", )} > -
+
{isCollapsed ? ( @@ -103,7 +116,11 @@ export function Sidebar({ isOpen, isCollapsed, onToggleCollapse, onClose }: Side onClick={onToggleCollapse} aria-label={isCollapsed ? "Expand sidebar" : "Collapse sidebar"} > - {isCollapsed ? : } + {isCollapsed ? ( + + ) : ( + + )}
- ) + ); } diff --git a/src/components/ui/input.tsx b/src/components/ui/input.tsx index c46b5cd..83cec90 100644 --- a/src/components/ui/input.tsx +++ b/src/components/ui/input.tsx @@ -1,21 +1,21 @@ -import * as React from "react" -import { cn } from "../../lib/utils" +import * as React from "react"; +import { cn } from "../../lib/utils"; export interface InputProps extends React.InputHTMLAttributes {} -export const Input = React.forwardRef(({ className, type, ...props }, ref) => { - return ( - - ) -}) -Input.displayName = "Input" - - +export const Input = React.forwardRef( + ({ className, type, ...props }, ref) => { + return ( + + ); + }, +); +Input.displayName = "Input"; diff --git a/src/components/ui/stepper.tsx b/src/components/ui/stepper.tsx index a4627aa..a0c87a2 100644 --- a/src/components/ui/stepper.tsx +++ b/src/components/ui/stepper.tsx @@ -1,61 +1,52 @@ -import * as React from "react" -import { Check } from "lucide-react" -import { cn } from "../../lib/utils" +import { cn } from "../../lib/utils"; export interface StepperProps { - steps: string[] - currentStep: number - className?: string + steps: string[]; + currentStep: number; + className?: string; } export function Stepper({ steps, currentStep, className }: StepperProps) { return ( -
+
{steps.map((step, index) => { - const stepNumber = index + 1 - const isCompleted = stepNumber < currentStep - const isCurrent = stepNumber === currentStep + const stepNumber = index + 1; + const isCurrent = stepNumber === currentStep; return ( - -
-
-
- {isCompleted ? : stepNumber} -
- - {step} - -
-
+
+ {/* Connector Line (Behind) */} {index < steps.length - 1 && ( -
+
)} - - ) + + {/* Circle */} +
+ {stepNumber} +
+ + {/* Label */} + + {step} + +
+ ); })}
- ) + ); } - diff --git a/src/pages/content-management/AddPracticeFlow.tsx b/src/pages/content-management/AddPracticeFlow.tsx new file mode 100644 index 0000000..7e3b742 --- /dev/null +++ b/src/pages/content-management/AddPracticeFlow.tsx @@ -0,0 +1,259 @@ +import { useState } from "react"; +import { + Link, + useNavigate, + useParams, + useSearchParams, +} from "react-router-dom"; +import { ArrowLeft } from "lucide-react"; +import { Button } from "../../components/ui/button"; +import { Stepper } from "../../components/ui/stepper"; +import successIcon from "../../assets/success.svg"; + +import { ContextStep } from "./components/practice-steps/ContextStep"; +import { ScenarioStep } from "./components/practice-steps/ScenarioStep"; +import { PersonaStep } from "./components/practice-steps/PersonaStep"; +import { QuestionsStep } from "./components/practice-steps/QuestionsStep"; +import { ReviewStep } from "./components/practice-steps/ReviewStep"; + +export function AddPracticeFlow() { + const navigate = useNavigate(); + const { level } = useParams<{ level: string }>(); + const [searchParams] = useSearchParams(); + const backTo = searchParams.get("backTo"); + const courseId = searchParams.get("courseId"); + const moduleId = searchParams.get("moduleId"); + + const isModuleContext = backTo === "module"; + + const backLabel = + backTo === "module" + ? "Back to Module" + : backTo === "modules" + ? "Back to Modules" + : "Back to Courses"; + const backPath = + backTo === "module" && courseId && moduleId + ? `/new-content/learn-english/${level}/courses/${courseId}/modules/${moduleId}` + : backTo === "modules" && courseId + ? `/new-content/learn-english/${level}/courses/${courseId}` + : `/new-content/learn-english/${level}/courses`; + + const flowSteps = isModuleContext + ? ["Context", "Persona", "Questions", "Review"] + : ["Context", "Scenario", "Persona", "Questions", "Review"]; + + const [currentStep, setCurrentStep] = useState(1); + const [selectedPersona, setSelectedPersona] = useState( + "dawit", + ); + const [isPublished, setIsPublished] = useState(false); + + const [formData, setFormData] = useState({ + program: "Intermediate", + course: "A2", + title: "", + description: "", + selectedVideo: "", + tips: "Focus on using the present perfect continuous tense to describe an action that started in the past and continues now.", + questions: [ + { + id: "q1", + text: "How long have you been studying English?", + type: "Speaking", + voicePrompt: "prompt_q1_en.mp3", + sampleAnswer: "prompt_q1_en.mp3", + }, + ], + }); + + const nextStep = () => + setCurrentStep((prev) => Math.min(prev + 1, flowSteps.length)); + const prevStep = () => setCurrentStep((prev) => Math.max(prev - 1, 1)); + + if (isPublished) { + return ( +
+
+
+ Success +
+

+ Practice Published Successfully! +

+

+ Your speaking practice is now active and available inside the module. +

+
+ + +
+
+ ); + } + + // Helper to map currentStep to the actual component for the module flow + const renderStep = () => { + if (!isModuleContext) { + switch (currentStep) { + case 1: + return ( + + ); + case 2: + return ( + + ); + case 3: + return ( + + ); + case 4: + return ( + + ); + case 5: + return ( + + ); + default: + return null; + } + } else { + // Module Context Flow (Skips Scenario) + switch (currentStep) { + case 1: + return ( + + ); + case 2: + return ( + + ); + case 3: + return ( + + ); + case 4: + return ( + + ); + default: + return null; + } + } + }; + + return ( +
+ {/* Header */} +
+
+ + + {backLabel} + + +
+ +
+

+ Add New Practice +

+

+ Create a new immersive practice session for students. +

+
+ +
+ +
+ +
{renderStep()}
+
+
+ ); +} diff --git a/src/pages/content-management/AddVideoFlow.tsx b/src/pages/content-management/AddVideoFlow.tsx new file mode 100644 index 0000000..7086bd4 --- /dev/null +++ b/src/pages/content-management/AddVideoFlow.tsx @@ -0,0 +1,155 @@ +import { useState } from "react"; +import { Link, useNavigate, useParams } from "react-router-dom"; +import { ArrowLeft, Check } from "lucide-react"; +import { Button } from "../../components/ui/button"; +import { Stepper } from "../../components/ui/stepper"; + +import { VideoDetailStep } from "./components/video-steps/VideoDetailStep"; +import { ReviewPublishStep } from "./components/video-steps/ReviewPublishStep"; + +const STEPS = [ + { id: 1, label: "Video Detail" }, + { id: 2, label: "Review & Publish" }, +]; + +export function AddVideoFlow() { + const navigate = useNavigate(); + const { level, courseId, moduleId } = useParams<{ + level: string; + courseId: string; + moduleId: string; + }>(); + const [currentStep, setCurrentStep] = useState(1); + const [isPublished, setIsPublished] = useState(false); + + const [formData, setFormData] = useState({ + title: "", + order: "1", + description: "", + thumbnail: null, + videoFile: null, + }); + + const nextStep = () => setCurrentStep((prev) => Math.min(prev + 1, 2)); + const prevStep = () => setCurrentStep((prev) => Math.max(prev - 1, 1)); + + const backPath = `/new-content/learn-english/${level}/courses/${courseId}/modules/${moduleId}`; + + if (isPublished) { + return ( +
+ {/* Success Icon Wrapper (Jagged Circle Style) */} +
+
+
+
+ +
+ {/* Sub-Jagged layer for depth if needed */} +
+
+
+ +

+ Video Published Successfully! +

+

+ Your video is now live and available inside the selected module. +

+ +
+ + +
+
+ ); + } + + return ( +
+ {/* Header */} +
+
+ + + Back to Modules + + +
+ +

+ Add New Video +

+ +
+ s.label)} + currentStep={currentStep} + /> +
+ + {/* Step Content */} +
+ {currentStep === 1 && ( + + )} + + {currentStep === 2 && ( + + )} +
+
+
+ ); +} diff --git a/src/pages/content-management/CourseDetailPage.tsx b/src/pages/content-management/CourseDetailPage.tsx new file mode 100644 index 0000000..52896fd --- /dev/null +++ b/src/pages/content-management/CourseDetailPage.tsx @@ -0,0 +1,160 @@ +import { useState } from "react"; +import { ArrowLeft, Plus, Calendar, Plane, Clock, Hand } from "lucide-react"; +import { Link, useNavigate, useParams } from "react-router-dom"; +import { Button } from "../../components/ui/button"; +import { Card } from "../../components/ui/card"; +import { cn } from "../../lib/utils"; + +const MODULES = [ + { + id: "m1", + title: "Introduction Basics", + description: "Learn basic English words, phrases, and simple sentences.", + icon: Hand, + status: "Published", + gradient: "from-[#8E44AD] to-[#C39BD3]", + }, + { + id: "m2", + title: "Daily Routines", + description: "Vocabulary related to waking up, and evening activities.", + icon: Clock, + status: "Draft", + gradient: "from-[#8E44AD] to-[#C39BD3]", + }, + { + id: "m3", + title: "Travel Essentials", + description: + "Key phrases for airports, hotels, and asking for help while abroad.", + icon: Plane, + status: "Draft", + gradient: "from-[#8E44AD] to-[#C39BD3]", + }, +]; + +import { AddModuleModal } from "./components/AddModuleModal"; + +export function CourseDetailPage() { + const navigate = useNavigate(); + const { level, courseId } = useParams<{ level: string; courseId: string }>(); + const [isAddModuleOpen, setIsAddModuleOpen] = useState(false); + + return ( +
+ {/* Header Navigation */} +
+ + + Back to Levels + +
+ + {/* Hero Section */} +
+
+

+ {courseId?.toUpperCase() || "A1"} +

+

+ Learn basic English words, phrases, and simple sentences for daily + situations. +

+
+
+ + +
+
+ + setIsAddModuleOpen(false)} + /> + + {/* Gradient Grid */} +
+ {MODULES.map((module) => ( + + {/* Gradient Banner */} +
+ +
+
+ {/* Icon Circle */} +
+ +
+ + {/* Content */} +
+

+ {module.title} +

+

+ {module.description} +

+
+
+ + {/* Actions */} +
+ + {module.status === "Published" ? ( + + ) : ( + + )} +
+
+ + ))} +
+
+ ); +} diff --git a/src/pages/content-management/LearnEnglishPage.tsx b/src/pages/content-management/LearnEnglishPage.tsx new file mode 100644 index 0000000..05e5070 --- /dev/null +++ b/src/pages/content-management/LearnEnglishPage.tsx @@ -0,0 +1,214 @@ +import { Plus, ArrowRight } from "lucide-react"; +import { Link } from "react-router-dom"; +import { Card, CardContent } from "../../components/ui/card"; +import { Button } from "../../components/ui/button"; +import { + Dialog, + DialogContent, + DialogHeader, + DialogTitle, + DialogDescription, + DialogTrigger, + DialogClose, +} from "../../components/ui/dialog"; +import { Input } from "../../components/ui/input"; +import { Select } from "../../components/ui/select"; +import uploadIcon from "../../assets/icons/upload.png"; + +export function LearnEnglishPage() { + const levels = [ + { + id: "beginner", + title: "Beginner", + description: + "Designed for learners starting from scratch. Focuses on simple grammar, and everyday communication.", + }, + { + id: "intermediate", + title: "Intermediate", + description: + "For learners who can communicate at a basic level and want to improve fluency, accuracy, and confidence.", + }, + { + id: "advanced", + title: "Advanced", + description: + "Targets advanced learners aiming for professional, academic, and complex conversational English.", + }, + ]; + + return ( +
+ {/* Header section */} +
+
+

+ Learn English +

+

+ Manage learning content by level +

+
+ + + + + + + + + Add New Program + + + Create a learning program to group courses by learner level + + + {/* Gradient Divider */} +
+
+
+ + {/* Gradient Divider */} +
+