- {projectsTableData.map(
+ {team&&team.map(
({ img, name, members, budget, completion }, key) => {
const className = `py-3 px-5 ${
key === projectsTableData.length - 1
@@ -147,7 +228,7 @@ export function Home() {
- {members.map(({ img, name }, key) => (
+ {members?.map(({ img, name }, key) => (
- Orders Overview
+ Overview
-
@@ -212,10 +293,10 @@ export function Home() {
className="h-3.5 w-3.5 text-green-500"
/>
24% this month
-
+ */}
- {ordersOverviewData.map(
+ {ordersOverviewData&&ordersOverviewData.map(
({ icon, color, title, description }, key) => (
{
+ if (auth) {
+ setLoading(true)
+ AuthApi.getUserData(auth)
+ .then(res => {
+ setLoading(false)
+ setUser(res.data.user)
+ })
+ .catch(err => {
+ setLoading(false)
+ console.log(err)
+ })
+ }
+ }, [])
+
return (
<>
-
-
-
-
-
-
-
-
- Richard Davis
-
-
- CEO / Co-Founder
-
+ {!loading && user && <>
+
+
+
+
+
+
+
+
+ {user?.firstName} {user?.lastName}
+
+
+ member
+
+
-
-
-
-
-
- App
-
-
-
- Message
-
-
-
- Settings
-
-
-
+
+
+ popup.run( popup.close()} />)} className="h-4 w-4 cursor-pointer text-blue-gray-500" />
+
+ }
+ />
-
-
-
-
- Platform Settings
+
+
+ Courses
-
- {platformSettingsData.map(({ title, options }) => (
-
-
- {title}
-
-
- {options.map(({ checked, label }) => (
-
- ))}
-
-
- ))}
-
-
-
-
-
-
-
- ),
- }}
- action={
-
-
-
- }
- />
-
-
- Platform Settings
+
+ Enrolled Courses
-
- {conversationsData.map((props) => (
-
- reply
-
- }
- />
- ))}
-
-
-
-
-
- Projects
-
-
- Architects design houses
-
-
- {projectsData.map(
- ({ img, title, description, tag, route, members }) => (
-
-
-
-
-
-
- {tag}
-
-
- {title}
-
-
+ {user?.myCourses.map(
+ ({ courseId: { courseImage, courseTitle, courseDescription, category, _id } }) => (
+
+
- {description}
-
-
-
-
-
-
-
- {members.map(({ img, name }, key) => (
-
-
-
- ))}
-
-
-
- )
- )}
+ 
+
+
+
+ {category}
+
+
+ {courseTitle}
+
+
+ {courseDescription.slice(0, 20)}
+
+
+
+
+
+
+
+
+ )
+ )}
+
-
-
-
+
+
+ >
+ }
+ {loading &&
+
+ }
+ {!loading && !user &&
+
+ No Data Found
+
+
+ }
>
);
}
+const EditUserDataModal = ({ setClose }) => {
+ const { auth, account } = useAuth();
+ const { openSnackbar } = useSnackbar()
+ const [loading, setLoading] = useState(false);
+ const [user, setUser] = useState({
+ firstName: account.firstName,
+ lastName: account.lastName,
+ email: account.email
+ });
+
+ const handleChange = (e) => {
+ setUser({ ...user, [e.target.name]: e.target.value })
+ }
+
+ const handleSubmit = (e) => {
+ e.preventDefault();
+ setLoading(!loading)
+ AuthApi.EditUserData(user, auth)
+ .then(res => {
+ setLoading(false)
+ console.log(res)
+ openSnackbar("Profile Updated Successfuly", { type: "success" })
+ setClose()
+ })
+ .catch(err => {
+ setLoading(false)
+ openSnackbar(err.response.data.message, { type: "error" })
+ console.log(err)
+ })
+ }
+
+ return (
+
+ )
+}
+
export default Profile;
diff --git a/src/pages/dashboard/tables.jsx b/src/pages/dashboard/tables.jsx
index 3d453ed7..fad5bfc4 100644
--- a/src/pages/dashboard/tables.jsx
+++ b/src/pages/dashboard/tables.jsx
@@ -17,14 +17,14 @@ export function Tables() {
- Authors Table
+ Payment History Table
- {["author", "function", "status", "employed", ""].map((el) => (
+ {["payment", "details", "status", "date", ""].map((el) => (
|
|
-
+ {/* */}
- {name}
+ {'$500'}
- {email}
+ {'bank account'}
|
- {job[0]}
+ {'invitaion'}
{job[1]}
@@ -79,7 +79,7 @@ export function Tables() {
|
@@ -88,7 +88,7 @@ export function Tables() {
{date}
-
+ {/* |
Edit
- |
+ */}
);
}
@@ -108,7 +108,7 @@ export function Tables() {
- Projects Table
+ Campain Table
@@ -156,7 +156,7 @@ export function Tables() {
- {members.map(({ img, name }, key) => (
+ {members?.map(({ img, name }, key) => (
{
+ const [courses, setCourses] = useState();
+ const [selectedCourse, setSelectedCourse] = useState(null);
+ const [isAddingCourse, setIsAddingCourse] = useState(false);
+ const [isAddingLesson, setIsAddingLesson] = useState(false);
+ const [newCourse, setNewCourse] = useState({ title: "", description: "" });
+ const [newLesson, setNewLesson] = useState({ title: "", description: "", file: null });
+ const [uploading, setUploading] = useState(false);
+ const [progress, setProgress] = useState(0);
+ const [error, setError] = useState("");
+ const [confirmDelete, setConfirmDelete] = useState(null); // State for delete confirmation
+const [editLesson, setEditLesson] = useState(null); // Stores the lesson being edited
+
+ const {auth, socket } = useAuth();
+ useEffect(() => {
+ socket.on("uploadProgress", (data) => {
+ setProgress(data.progress);
+ });
+
+ // Fetch existing courses
+ fetchCourses();
+
+ return () => {
+ // socket.off("uploadProgress");
+ };
+ }, []);
+
+ const fetchCourses = async () => {
+ try {
+ const response = await CoursesApi.getAllCourses(10, 1);
+ console.log(response)
+ const transformedCourses = response.data.courses.map((course) => ({
+ id: course._id, // Map _id to id
+ title: course.courseTitle, // Map courseTitle to title
+ description: course.courseDescription, // Map courseDescription to description
+ image: course.courseImage, // Use courseImage
+ lessons: course.lessons.map(({_id,lessonTitle,lessonDescription}) => ({
+ id: _id, // Keep lesson IDs (optionally resolve full lesson data here)
+ title: lessonTitle, // Placeholder if no full data is available
+ description: lessonDescription, // Placeholder if no full data is available
+ })),
+ members: course.members, // Keep members as-is
+ totalMembers: course.totalMembers, // Keep total members
+ category: course.category, // Use category
+ }));
+ console.log(transformedCourses)
+ setCourses(transformedCourses);
+ } catch (err) {
+ setError("Failed to fetch courses");
+ }
+};
+ useEffect(()=>{
+ console.log(courses,'the co')
+ },[courses])
+
+ const handleCreateCourse = async () => {
+ const formData = new FormData();
+ formData.append("file", newCourse.image);
+ formData.append("courseTitle", newCourse.title);
+ formData.append("courseDescription", newCourse.description);
+ formData.append("coursePrice", newCourse.price);
+ formData.append("category", newCourse.category);
+ formData.append("folder", "courses");
+ console.log(newCourse)
+ try {
+ // Replace with your actual API endpoint
+ // const response = await CoursesApi.addCourse(formData,auth);
+ const response = await axios.post("https://sea-turtle-app-rwcjs.ondigitalocean.app/api/v1/course/addCourse", formData, {
+ headers: {
+ "token":auth,
+ "Content-Type": "multipart/form-data",
+ "x-socket-id": socket.id,
+ },
+ });
+ setCourses([...courses, newCourse]);
+ setIsAddingCourse(false);
+ setNewCourse({ title: "", description: "" });
+ } catch (err) {
+ setError("Failed to create course");
+ }
+ };
+
+ const handleUploadLesson = async () => {
+ if (!newLesson.file || !selectedCourse) {
+ setError("Please select a file and course");
+ return;
+ }
+
+ const formData = new FormData();
+ formData.append("video", newLesson.file);
+ formData.append("image", newLesson.image);
+ formData.append("lessonTitle", newLesson.title);
+ formData.append("lessonDescription", newLesson.description);
+ formData.append("courseId", selectedCourse.id);
+ formData.append("folder", "lessons");
+
+ try {
+ setUploading(true);
+ setProgress(0);
+ setError("");
+
+ const response = await axios.post(`https://sea-turtle-app-rwcjs.ondigitalocean.app/api/v1/course/${selectedCourse.id}/lessons`, formData, {
+ headers: {
+ "token":auth,
+ "Content-Type": "multipart/form-data",
+ "x-socket-id": socket.id,
+ },
+ });
+ // let data = {...courses}
+ // let idex = data.findIndex(e=>e.id === selectedCourse.id)
+ // data[idex].lessons.push(
+ // {
+ // id: 'test',
+ // title: newLesson.title,
+ // description: newLesson.description,
+ // }
+ // )
+ // Update the course with the new lesson
+ fetchCourses();
+ setIsAddingLesson(false);
+ setNewLesson({ title: "", description: "", file: null });
+ } catch (err) {
+ setError("Failed to upload lesson");
+ } finally {
+ setUploading(false);
+ }
+ };
+ const handleDeleteCourse = async (courseId) => {
+ try {
+ await axios.delete(`https://sea-turtle-app-rwcjs.ondigitalocean.app/api/v1/course/${courseId}`, {
+ headers: { token: auth },
+ });
+
+ setCourses(courses.filter((course) => course.id !== courseId));
+ setSelectedCourse(null);
+ setConfirmDelete(null); // Close confirmation dialog
+ } catch (err) {
+ setError("Failed to delete course");
+ }
+ };
+
+const handleDeleteLesson = async (lessonId, courseId) => {
+ try {
+ await axios.delete(`https://sea-turtle-app-rwcjs.ondigitalocean.app/api/v1/course/lessons/${lessonId}`, {
+ headers: { token: auth },
+ });
+
+ setCourses((prevCourses) =>
+ prevCourses.map((course) =>
+ course.id === courseId
+ ? { ...course, lessons: course.lessons.filter((lesson) => lesson.id !== lessonId) }
+ : course
+ )
+ );
+ setConfirmDelete(null); // Close confirmation dialog
+ } catch (err) {
+ setError("Failed to delete lesson");
+ }
+ };
+const handleEditLesson = async () => {
+ const formData = new FormData();
+ formData.append("lessonTitle", editLesson.title);
+ formData.append("lessonDescription", editLesson.description);
+
+ if (editLesson.video) {
+ formData.append("video", editLesson.video);
+ }
+ if (editLesson.image) {
+ formData.append("image", editLesson.image);
+ }
+
+ try {
+ const response = await axios.put(
+ `https://sea-turtle-app-rwcjs.ondigitalocean.app/api/v1/course/editLesson/${editLesson.id}`,
+ formData,
+ {
+ headers: {
+ token: auth,
+ "Content-Type": "multipart/form-data",
+ },
+ }
+ );
+
+ const updatedLesson = response.data.lesson;
+
+ // Update the lessons in the selected course
+ setCourses((prevCourses) =>
+ prevCourses.map((course) =>
+ course.id === selectedCourse.id
+ ? {
+ ...course,
+ lessons: course.lessons.map((lesson) =>
+ lesson.id === updatedLesson._id ? updatedLesson : lesson
+ ),
+ }
+ : course
+ )
+ );
+
+ setEditLesson(null); // Close modal
+ } catch (err) {
+ setError("Failed to update lesson");
+ }
+};
+
+ return (
+
+ {/* Header */}
+
+
+ Course Management
+
+
+
+ {/* Main Content */}
+
+
+ {/* Courses Sidebar */}
+
+
+
+ Courses
+
+
+
+
+ {courses&&courses.map((course) => {
+ return (
+ setSelectedCourse(course)}
+ >
+
+
+ {course.title}
+
+
+
+ )})}
+
+
+
+ {/* Main Content Area */}
+
+ {selectedCourse ? (
+
+
+
+ {selectedCourse.title}
+ {selectedCourse.description}
+
+
+
+
+ {/* Lessons List */}
+
+ {selectedCourse.lessons?.map((lesson) => (
+
+
+
+
+
+ {lesson.title}
+ {lesson.description}
+
+
+
+
+
+
+
+
+ ))}
+
+
+ ) : (
+
+ Select a course or create a new one to get started
+
+ )}
+
+
+
+ {editLesson && (
+
+
+ Edit Lesson
+
+ {/* Lesson Title */}
+ setEditLesson({ ...editLesson, title: e.target.value })}
+ className="w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
+ placeholder="Lesson Title"
+ />
+
+ {/* Lesson Description */}
+
+
+
+
+
+
+
+)}
+
+ {/* Add Course Modal */}
+ {isAddingCourse && (
+
+
+ Add New Course
+
+
+
+ {
+ e.preventDefault();
+ e.stopPropagation();
+ }}
+ onDrop={(e) => {
+ e.preventDefault();
+ e.stopPropagation();
+ const file = e.dataTransfer.files[0];
+ if (file && file.type.startsWith("image/")) {
+ setNewCourse({ ...newCourse, image: file });
+ }
+ }}
+ >
+ setNewCourse({ ...newCourse, image: e.target.files[0] })}
+ accept="image/*"
+ className="hidden"
+ id="course-image"
+ />
+
+
+
+
+
+
+ setNewCourse({ ...newCourse, title: e.target.value })}
+ className="w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
+ placeholder="Enter course title"
+ />
+
+
+
+
+
+
+ setNewCourse({ ...newCourse, price: e.target.value })}
+ className="w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
+ placeholder="Enter course price"
+ type="number"
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+ )}
+ {confirmDelete && (
+
+
+
+ {confirmDelete.type === "course"
+ ? "Are you sure you want to delete this course?"
+ : "Are you sure you want to delete this lesson?"}
+
+
+
+
+
+
+
+ )}
+ {/* Add Lesson Modal */}
+ {isAddingLesson && (
+
+
+ Add New Lesson
+
+
+
+ setNewLesson({ ...newLesson, title: e.target.value })}
+ className="w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
+ placeholder="Enter lesson title"
+ />
+
+
+
+
+
+
+ {
+ e.preventDefault();
+ e.stopPropagation();
+ }}
+ onDrop={(e) => {
+ e.preventDefault();
+ e.stopPropagation();
+ const file = e.dataTransfer.files[0];
+ if (file && file.type.startsWith('video/')) {
+ setNewLesson({ ...newLesson, file });
+ }
+ }}
+ >
+ setNewLesson({ ...newLesson, file: e.target.files[0] })}
+ accept="video/*"
+ className="hidden"
+ id="lesson-video"
+ />
+
+
+
+ {
+ e.preventDefault();
+ e.stopPropagation();
+ }}
+ onDrop={(e) => {
+ e.preventDefault();
+ e.stopPropagation();
+ const file = e.dataTransfer.files[0];
+ if (file && file.type.startsWith('image/')) {
+ setNewLesson({ ...newLesson, image:file });
+ }
+ }}
+ >
+ setNewLesson({ ...newLesson, image: e.target.files[0] })}
+ accept="image/*"
+ className="hidden"
+ id="lesson-image"
+ />
+
+
+
+
+ {uploading && (
+
+
+ {progress}% uploaded
+
+ )}
+
+ {error && (
+
+ )}
+
+
+
+
+
+
+
+
+ )}
+
+ );
+};
+
+export default CourseManagement;
\ No newline at end of file
diff --git a/src/pages/terms/ContactUs.jsx b/src/pages/terms/ContactUs.jsx
new file mode 100644
index 00000000..7c1fc7b7
--- /dev/null
+++ b/src/pages/terms/ContactUs.jsx
@@ -0,0 +1,303 @@
+import { useLang } from "../../hooks/LangContext";
+import { useEffect, useState } from "react";
+import { useExpand } from "../../hooks/ExpandSide";
+import Auth from "@/api/Auth.api";
+import { useSnackbar } from "../../hooks/SnackBar";
+import { useNavigate } from "react-router-dom";
+import { useAuth } from "../../hooks/Auth";
+import PropTypes from "prop-types";
+import {
+ Card,
+ CardHeader,
+ CardBody,
+ Typography,
+ Avatar,
+ Chip,
+ Tooltip,
+ Progress,
+ Input,
+ Checkbox,
+ Button,
+ Textarea,
+} from "@material-tailwind/react";
+import { LoaderCircle } from "lucide-react";
+import PageNumbers from "@/components/pageNumbers";
+export default function ContactUs() {
+ const [search, setSearch] = useState(null);
+ const { openSnackbar } = useSnackbar();
+ const { auth, account } = useAuth();
+ const [adminMessages, setAdminMessages] = useState([]);
+ const [contactUs, setContactUs] = useState({
+ firstName: "",
+ lastName: "",
+ phone: "",
+ email: "",
+ message: "",
+ });
+ const [loading, setLoading] = useState(false);
+ const [limit, setLimit] = useState(20);
+ const [page, setPage] = useState(1);
+ const [pagesNumber, setPagesNumber] = useState(1);
+ const nav = useNavigate();
+ useEffect(() => {
+ console.log(contactUs);
+ }, [contactUs]);
+ const handleContactUsChange = (e) => {
+ const { name, value } = e.target;
+
+ setContactUs((prev) => ({
+ ...prev,
+ [name]: value,
+ }));
+ };
+
+ const next = (num) => {
+ if (num) {
+ setPage(num)
+ return
+ }
+ if (page + 1 > pagesNumber) return
+ setPage(page + 1)
+ }
+
+ const prev = () => {
+ if (page - 1 <= 0) return
+ setPage(page - 1)
+ }
+
+
+ const handleSubmit = (e) => {
+ e.preventDefault();
+ setLoading(true);
+ Auth.contactUs(contactUs, auth)
+ .then(() => {
+ openSnackbar("Message Sent Successfully", {
+ type: "success",
+ duration: 3000,
+ });
+ setLoading(false);
+ nav("/home");
+ })
+ .catch((err) => {
+ setLoading(false);
+ openSnackbar(err.response.data.msg, {
+ type: "error",
+ duration: 4000,
+ });
+ });
+ };
+
+ useEffect(() => {
+ if (account.role === "admin") {
+ setLoading(true);
+ Auth.getContactUs(auth, limit, page)
+ .then((res) => {
+ setLoading(false);
+ setPagesNumber(res.data.totalPages);
+ setAdminMessages(res.data.issues);
+ })
+ .catch((err) => {
+ setLoading(false);
+ console.log(err);
+ });
+ }
+ }, [page]);
+
+ const { lang } = useLang();
+ return (
+
+
+ {/* */}
+
+ {/* */}
+ {account.role !== "admin" && (
+
+ )}
+ {account.role === "admin" && (
+ <>
+
+
+
+ Contact Us Messages
+
+
+
+ {adminMessages.length === 0 || loading ? (
+
+
+
+ ) : (
+
+
+
+ {["name", "email", "phone", "message", "date", ""].map((el) => (
+ |
+
+ {el}
+
+ |
+ ))}
+
+
+
+ {adminMessages.map(
+ ({ _id, firstName, lastName , email, phone, createdAt, message }, key) => {
+ const className = `py-3 px-5 ${key === adminMessages.length - 1
+ ? ""
+ : "border-b border-blue-gray-50"
+ }`;
+
+ return (
+
+
+
+
+
+ {firstName} {lastName}
+
+
+
+ |
+
+
+ {email}
+
+ |
+
+
+ |
+
+
+ {message.slice(0, 20)}
+
+ |
+
+
+ {new Date(createdAt).toLocaleString()}
+
+ |
+
+ );
+ }
+ )}
+
+
+ )}
+
+
+ {pagesNumber > 1 && }
+ >
+ )}
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/pages/terms/Terms.jsx b/src/pages/terms/Terms.jsx
new file mode 100644
index 00000000..0a0f83f4
--- /dev/null
+++ b/src/pages/terms/Terms.jsx
@@ -0,0 +1,65 @@
+import {
+ Typography,
+ Card,
+ CardHeader,
+ CardBody,
+} from "@material-tailwind/react";
+
+export function Terms() {
+ return (
+
+
+
+
+ Terms and Conditions
+
+
+
+
+ Introduction
+
+
+ Welcome to our application. These terms and conditions outline the rules and regulations for the use of our service.
+
+
+ Intellectual Property Rights
+
+
+ Other than the content you own, under these Terms, we own all the intellectual property rights and materials contained in this application.
+
+
+ Restrictions
+
+
+ You are specifically restricted from all of the following:
+
+ - Publishing any application material in any other media
+ - Selling, sublicensing and/or otherwise commercializing any application material
+ - Publicly performing and/or showing any application material
+ - Using this application in any way that is or may be damaging to this application
+ - Using this application in any way that impacts user access to this application
+ - Using this application contrary to applicable laws and regulations
+
+
+
+ Your Privacy
+
+
+ Please read our Privacy Policy.
+
+
+ Limitation of Liability
+
+
+ In no event shall we, nor any of our officers, directors and employees, be held liable for anything arising out of or in any way connected with your use of this application.
+
+
+
+
+ );
+}
+
+export default Terms;
\ No newline at end of file
diff --git a/src/pages/terms/index.js b/src/pages/terms/index.js
new file mode 100644
index 00000000..a3adaf0f
--- /dev/null
+++ b/src/pages/terms/index.js
@@ -0,0 +1,2 @@
+export * from "@/pages/terms/Terms";
+export * from "@/pages/terms/ContactUs";
\ No newline at end of file
diff --git a/src/routes.jsx b/src/routes.jsx
index 3a5a8da0..a0c11373 100644
--- a/src/routes.jsx
+++ b/src/routes.jsx
@@ -5,14 +5,27 @@ import {
InformationCircleIcon,
ServerStackIcon,
RectangleStackIcon,
+ WalletIcon
} from "@heroicons/react/24/solid";
-import { Home, Profile, Tables, Notifications } from "@/pages/dashboard";
+import { Home, Profile, Tables, Notifications, Courses, CourseManager, PackagesManager, Packages, Course, Player, Signals } from "@/pages/dashboard";
import { SignIn, SignUp } from "@/pages/auth";
+import { Terms } from "@/pages/terms";
+import { Boxes, GraduationCap, Handshake, Headset, SignalHigh, Video } from "lucide-react";
+import ContactUs from "./pages/terms/ContactUs";
+import { useAuth } from "./hooks/Auth";
+import ViewPackage from "./pages/dashboard/Package";
+import MyCourses from "./pages/dashboard/MyCourses";
+import MyPackages from "./pages/dashboard/MyPackages";
+import { AgentSupportDashboard } from "./components/Support";
+import WalletDashboard from "./pages/dashboard/Wallet";
+import AdminDashboardPage from "./pages/dashboard/AdminWallet";
+import CourseUploader from "./pages/dashboard/uploadCourses";
const icon = {
className: "w-5 h-5 text-inherit",
};
+
export const routes = [
{
layout: "dashboard",
@@ -23,24 +36,125 @@ export const routes = [
path: "/home",
element: ,
},
+ {
+ icon: ,
+ name: "Support",
+ path: "/support",
+ element: ,
+ role: "support"
+ },
+
+ {
+ icon: ,
+ name: "Courses",
+ path: "/courses",
+ element: ,
+ },
+ {
+ icon: ,
+ name: "My Courses",
+ path: "/my-courses",
+ element: ,
+ role: "user"
+ },
+ {
+ icon: ,
+ name: "Course",
+ path: "/course/:id",
+ element: ,
+ },
+ // {
+ // icon: ,
+ // name: "Course uploader",
+ // path: "/courseUploader",
+ // element: ,
+ // role:'admin',
+ // },
+ {
+ icon: ,
+ name: "Courses Manager",
+ path: "/courses-manager",
+ element: ,
+ role: "admin"
+ },
+ {
+ icon: ,
+ name: "Packages",
+ path: "/packages",
+ element: ,
+ },
+ {
+ icon: ,
+ name: "My Packages",
+ path: "/my-packages",
+ element: ,
+ role: "user"
+ },
+ {
+ icon: ,
+ name: "Package",
+ path: "/package/:id",
+ element: ,
+ },
+ {
+ icon: ,
+ name: "Packages Manager",
+ path: "/packages-manager",
+ element: ,
+ role: "admin"
+ },
{
icon: ,
name: "profile",
path: "/profile",
element: ,
+ role: "user"
+ },
+ {
+ icon: ,
+ name: "wallet",
+ path: "/wallet",
+ element: ,
+ role: "user"
+ },
+ {
+ icon: ,
+ name: "adminWallet",
+ path: "/adminWallet",
+ element: ,
+ role: "admin"
},
{
- icon: ,
- name: "tables",
- path: "/tables",
- element: ,
+ icon: ,
+ name: "signals",
+ path: "/signals",
+ element: ,
+ role: "admin"
},
+ // {
+ // icon: ,
+ // name: "tables",
+ // path: "/tables",
+ // element: ,
+ // },
{
- icon: ,
- name: "notifications",
- path: "/notifications",
- element: ,
+ icon: ,
+ name: "Contact Us",
+ path: "/contact-us",
+ element: ,
},
+ // {
+ // icon: ,
+ // name: "notifications",
+ // path: "/notifications",
+ // element: ,
+ // },
+ {
+ icon: ,
+ name: "lesson",
+ path: "/lesson/:id/course/:courseId",
+ element: ,
+ }
],
},
{
@@ -61,6 +175,19 @@ export const routes = [
},
],
},
+ {
+ title: "terms and conditions",
+ layout: "terms",
+ pages: [
+ {
+ icon: ,
+ name: "terms and conditions",
+ path: "/terms-and-conditions",
+ element: ,
+ },
+
+ ]
+ },
];
export default routes;
diff --git a/src/widgets/layout/dashboard-navbar.jsx b/src/widgets/layout/dashboard-navbar.jsx
index d91e23f7..2a320867 100644
--- a/src/widgets/layout/dashboard-navbar.jsx
+++ b/src/widgets/layout/dashboard-navbar.jsx
@@ -1,4 +1,4 @@
-import { useLocation, Link } from "react-router-dom";
+import { useLocation, Link, useNavigate } from "react-router-dom";
import {
Navbar,
Typography,
@@ -22,33 +22,108 @@ import {
} from "@heroicons/react/24/solid";
import {
useMaterialTailwindController,
- setOpenConfigurator,
setOpenSidenav,
} from "@/context";
+import { useAuth } from "@/hooks/Auth";
+import { useEffect, useRef, useState } from "react";
+import { LogOut } from "lucide-react";
+import { AnimatePresence, motion } from 'framer-motion';
export function DashboardNavbar() {
+ const { account, signout, search, setSearch } = useAuth();
const [controller, dispatch] = useMaterialTailwindController();
const { fixedNavbar, openSidenav } = controller;
const { pathname } = useLocation();
const [layout, page] = pathname.split("/").filter((el) => el !== "");
+ const [isProfileOpen, setIsProfileOpen] = useState(false);
+ const profileCardRef = useRef(null);
+ let photoLink = account.photoLink || "https://res.cloudinary.com/dqdt57lxl/image/upload/v1733091929/jhl718s0eucpxdyqpzqh.png";
+ const nav = useNavigate()
+ const toggleProfile = () => {
+ setIsProfileOpen((prevState) => !prevState);
+ console.log("Profile open state:", !isProfileOpen);
+ };
+
+ useEffect(() => {
+ const handleClickOutside = (e) => {
+ if (isProfileOpen && profileCardRef.current && !profileCardRef.current.contains(e.target)) {
+ setIsProfileOpen(false);
+ console.log("Clicked outside, closing profile card");
+ }
+ };
+
+ const timeoutId = setTimeout(() => {
+ window.addEventListener("click", handleClickOutside);
+ }, 0);
+
+ return () => {
+ clearTimeout(timeoutId);
+ window.removeEventListener("click", handleClickOutside);
+ };
+ }, [isProfileOpen, profileCardRef]);
+
+ const ProfileCard = () => {
+ const variants = {
+ hidden: { opacity: 0, y: -20 },
+ visible: { opacity: 1, y: 0 },
+ exit: { opacity: 0, y: -20 }
+ };
+
+ return (
+
+
+
+ 
+
+
+ {account.role !== "admin" ? account.firstName + " " + account.lastName : account.name}
+
+ {account.email}
+
+
+
+
+
+ );
+ };
return (
-
+ setSearch(e.target.value)} label="Search" />
setOpenSidenav(dispatch, !openSidenav)}
>
-
+
+
+
+
+ {isProfileOpen && }
+
+
+ {photoLink ? : }
-
-
-
-
-
-
- setOpenConfigurator(dispatch, true)}
- >
-
-
@@ -193,4 +263,4 @@ export function DashboardNavbar() {
DashboardNavbar.displayName = "/src/widgets/layout/dashboard-navbar.jsx";
-export default DashboardNavbar;
+export default DashboardNavbar;
\ No newline at end of file
diff --git a/src/widgets/layout/footer.jsx b/src/widgets/layout/footer.jsx
index 1ea98e53..58624867 100644
--- a/src/widgets/layout/footer.jsx
+++ b/src/widgets/layout/footer.jsx
@@ -41,13 +41,11 @@ export function Footer({ brandName, brandLink, routes }) {
}
Footer.defaultProps = {
- brandName: "Creative Tim",
- brandLink: "https://www.creative-tim.com",
routes: [
- { name: "Creative Tim", path: "https://www.creative-tim.com" },
- { name: "About Us", path: "https://www.creative-tim.com/presentation" },
- { name: "Blog", path: "https://www.creative-tim.com/blog" },
- { name: "License", path: "https://www.creative-tim.com/license" },
+ { name: "Backbenchers", path: "" },
+ { name: "About Us", path: "" },
+ { name: "Blog", path: "" },
+ { name: "License", path: "" },
],
};
diff --git a/src/widgets/layout/navbar.jsx b/src/widgets/layout/navbar.jsx
index ba0bd4c7..b4b6b086 100644
--- a/src/widgets/layout/navbar.jsx
+++ b/src/widgets/layout/navbar.jsx
@@ -83,7 +83,7 @@ export function Navbar({ brandName, routes, action }) {
}
Navbar.defaultProps = {
- brandName: "Material Tailwind React",
+ brandName: "Mentor Academy 🔥",
action: (
-
+
- {routes.map(({ layout, title, pages }, key) => (
-
- {title && (
- -
-
- {title}
-
-
- )}
- {pages.map(({ icon, name, path }) => (
- -
-
- {({ isActive }) => (
-
- )}
-
-
- ))}
-
- ))}
+ {title}
+
+
+ )}
+ {pages
+ .filter((page) => !page.role || page.role === account.role)
+ .map(({ icon, name, path }) => (
+ name !== "Course" &&name !== "Package" &&name !== "lesson" &&
+
+ {({ isActive }) => (
+
+ )}
+
+
+ ))}
+
+ )
+ )}
+
);
@@ -97,7 +118,7 @@ export function Sidenav({ brandImg, brandName, routes }) {
Sidenav.defaultProps = {
brandImg: "/img/logo-ct.png",
- brandName: "Material Tailwind React",
+ brandName: "Mentor Academy",
};
Sidenav.propTypes = {
@@ -108,4 +129,4 @@ Sidenav.propTypes = {
Sidenav.displayName = "/src/widgets/layout/sidnave.jsx";
-export default Sidenav;
+export default Sidenav;
\ No newline at end of file
diff --git a/tailwind.config.cjs b/tailwind.config.cjs
index 7ebd1762..b42e74d8 100644
--- a/tailwind.config.cjs
+++ b/tailwind.config.cjs
@@ -4,7 +4,13 @@ const withMT = require("@material-tailwind/react/utils/withMT");
module.exports = withMT({
content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
theme: {
- extend: {},
+ extend: {
+ colors: {
+ "vid-player-bg": "#1E1E1E",
+ "vid-player-controls-bg": "#0B0B0B",
+ "page-bg": "#1A1A1A",
+ }
+ },
},
plugins: [],
});
| |