diff --git a/api.ts b/api.ts index 1b076e3..203c67a 100644 --- a/api.ts +++ b/api.ts @@ -66,5 +66,6 @@ export const API = { }, Chatbot:{ CHAT: `${API_URL_ROOT}/chatbot/chat`, + HISTORY: `${API_URL_ROOT}/chatbot/history`, } } diff --git a/package-lock.json b/package-lock.json index 300c84b..854c7a6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { - "name": "fe_admin_history_web", + "name": "ultra_history_map", "version": "2.2.3", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "fe_admin_history_web", + "name": "ultra_history_map", "version": "2.2.3", "dependencies": { "@fullcalendar/core": "^6.1.19", diff --git a/public/images/brand/brand-01.svg b/public/images/brand/brand-01.svg deleted file mode 100644 index 7321fbf..0000000 --- a/public/images/brand/brand-01.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/public/images/brand/brand-02.svg b/public/images/brand/brand-02.svg deleted file mode 100644 index 14da422..0000000 --- a/public/images/brand/brand-02.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/public/images/brand/brand-03.svg b/public/images/brand/brand-03.svg deleted file mode 100644 index 8d29afa..0000000 --- a/public/images/brand/brand-03.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/public/images/brand/brand-04.svg b/public/images/brand/brand-04.svg deleted file mode 100644 index 837a4d4..0000000 --- a/public/images/brand/brand-04.svg +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/images/brand/brand-05.svg b/public/images/brand/brand-05.svg deleted file mode 100644 index 7044f46..0000000 --- a/public/images/brand/brand-05.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/public/images/brand/brand-06.svg b/public/images/brand/brand-06.svg deleted file mode 100644 index 78c5d01..0000000 --- a/public/images/brand/brand-06.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/public/images/brand/brand-07.svg b/public/images/brand/brand-07.svg deleted file mode 100644 index 5abb368..0000000 --- a/public/images/brand/brand-07.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/public/images/brand/brand-08.svg b/public/images/brand/brand-08.svg deleted file mode 100644 index 71bc1e2..0000000 --- a/public/images/brand/brand-08.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/public/images/brand/brand-09.svg b/public/images/brand/brand-09.svg deleted file mode 100644 index 1330ba2..0000000 --- a/public/images/brand/brand-09.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/public/images/brand/brand-10.svg b/public/images/brand/brand-10.svg deleted file mode 100644 index 60308dd..0000000 --- a/public/images/brand/brand-10.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/public/images/brand/brand-11.svg b/public/images/brand/brand-11.svg deleted file mode 100644 index b316bb4..0000000 --- a/public/images/brand/brand-11.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/public/images/brand/brand-12.svg b/public/images/brand/brand-12.svg deleted file mode 100644 index 8396a56..0000000 --- a/public/images/brand/brand-12.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/public/images/brand/brand-13.svg b/public/images/brand/brand-13.svg deleted file mode 100644 index dd53f79..0000000 --- a/public/images/brand/brand-13.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/public/images/brand/brand-14.svg b/public/images/brand/brand-14.svg deleted file mode 100644 index 381d72d..0000000 --- a/public/images/brand/brand-14.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/public/images/brand/brand-15.svg b/public/images/brand/brand-15.svg deleted file mode 100644 index dfde3dd..0000000 --- a/public/images/brand/brand-15.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/public/images/cards/card-01.jpg b/public/images/cards/card-01.jpg deleted file mode 100644 index 6ca5220..0000000 Binary files a/public/images/cards/card-01.jpg and /dev/null differ diff --git a/public/images/cards/card-01.png b/public/images/cards/card-01.png deleted file mode 100644 index 50136d2..0000000 Binary files a/public/images/cards/card-01.png and /dev/null differ diff --git a/public/images/cards/card-02.jpg b/public/images/cards/card-02.jpg deleted file mode 100644 index 4529105..0000000 Binary files a/public/images/cards/card-02.jpg and /dev/null differ diff --git a/public/images/cards/card-02.png b/public/images/cards/card-02.png deleted file mode 100644 index 29e3c40..0000000 Binary files a/public/images/cards/card-02.png and /dev/null differ diff --git a/public/images/cards/card-03.jpg b/public/images/cards/card-03.jpg deleted file mode 100644 index dea4663..0000000 Binary files a/public/images/cards/card-03.jpg and /dev/null differ diff --git a/public/images/cards/card-03.png b/public/images/cards/card-03.png deleted file mode 100644 index b8c8ed0..0000000 Binary files a/public/images/cards/card-03.png and /dev/null differ diff --git a/public/images/carousel/carousel-01.png b/public/images/carousel/carousel-01.png deleted file mode 100644 index 0c738c8..0000000 Binary files a/public/images/carousel/carousel-01.png and /dev/null differ diff --git a/public/images/carousel/carousel-02.png b/public/images/carousel/carousel-02.png deleted file mode 100644 index 963ca5f..0000000 Binary files a/public/images/carousel/carousel-02.png and /dev/null differ diff --git a/public/images/carousel/carousel-03.png b/public/images/carousel/carousel-03.png deleted file mode 100644 index d744261..0000000 Binary files a/public/images/carousel/carousel-03.png and /dev/null differ diff --git a/public/images/carousel/carousel-04.png b/public/images/carousel/carousel-04.png deleted file mode 100644 index 58d393d..0000000 Binary files a/public/images/carousel/carousel-04.png and /dev/null differ diff --git a/public/images/country/country-01.svg b/public/images/country/country-01.svg deleted file mode 100644 index 4c14b12..0000000 --- a/public/images/country/country-01.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/public/images/country/country-02.svg b/public/images/country/country-02.svg deleted file mode 100644 index 52f57c7..0000000 --- a/public/images/country/country-02.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/public/images/country/country-03.svg b/public/images/country/country-03.svg deleted file mode 100644 index e435fab..0000000 --- a/public/images/country/country-03.svg +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/public/images/country/country-04.svg b/public/images/country/country-04.svg deleted file mode 100644 index 93b49b6..0000000 --- a/public/images/country/country-04.svg +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/images/country/country-05.svg b/public/images/country/country-05.svg deleted file mode 100644 index 5aa26b5..0000000 --- a/public/images/country/country-05.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/public/images/country/country-06.svg b/public/images/country/country-06.svg deleted file mode 100644 index 730e2e6..0000000 --- a/public/images/country/country-06.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/public/images/country/country-07.svg b/public/images/country/country-07.svg deleted file mode 100644 index ce770d4..0000000 --- a/public/images/country/country-07.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/public/images/country/country-08.svg b/public/images/country/country-08.svg deleted file mode 100644 index c652b95..0000000 --- a/public/images/country/country-08.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/public/images/product/product-01.jpg b/public/images/product/product-01.jpg deleted file mode 100644 index 7ffb1e6..0000000 Binary files a/public/images/product/product-01.jpg and /dev/null differ diff --git a/public/images/product/product-02.jpg b/public/images/product/product-02.jpg deleted file mode 100644 index db30a9a..0000000 Binary files a/public/images/product/product-02.jpg and /dev/null differ diff --git a/public/images/product/product-03.jpg b/public/images/product/product-03.jpg deleted file mode 100644 index 95fd8d4..0000000 Binary files a/public/images/product/product-03.jpg and /dev/null differ diff --git a/public/images/product/product-04.jpg b/public/images/product/product-04.jpg deleted file mode 100644 index 131a9f5..0000000 Binary files a/public/images/product/product-04.jpg and /dev/null differ diff --git a/public/images/product/product-05.jpg b/public/images/product/product-05.jpg deleted file mode 100644 index 1ad17a9..0000000 Binary files a/public/images/product/product-05.jpg and /dev/null differ diff --git a/public/images/video-thumb/thumb-16.png b/public/images/video-thumb/thumb-16.png deleted file mode 100644 index 1f12017..0000000 Binary files a/public/images/video-thumb/thumb-16.png and /dev/null differ diff --git a/public/images/video-thumb/youtube-icon-84.svg b/public/images/video-thumb/youtube-icon-84.svg deleted file mode 100644 index 5a9478a..0000000 --- a/public/images/video-thumb/youtube-icon-84.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/app/(admin)/(ui-elements)/alerts/page.tsx b/src/app/(admin)/(ui-elements)/alerts/page.tsx deleted file mode 100644 index d26561e..0000000 --- a/src/app/(admin)/(ui-elements)/alerts/page.tsx +++ /dev/null @@ -1,86 +0,0 @@ -import ComponentCard from "@/components/common/ComponentCard"; -import PageBreadcrumb from "@/components/common/PageBreadCrumb"; -import Alert from "@/components/ui/alert/Alert"; -import { Metadata } from "next"; -import React from "react"; - -export const metadata: Metadata = { - title: "Next.js Alerts | TailAdmin - Next.js Dashboard Template", - description: - "This is Next.js Alerts page for TailAdmin - Next.js Tailwind CSS Admin Dashboard Template", - // other metadata -}; - -export default function Alerts() { - return ( -
- -
- - - - - - - - {" "} - - - - {" "} - - - - -
-
- ); -} diff --git a/src/app/(admin)/(ui-elements)/avatars/page.tsx b/src/app/(admin)/(ui-elements)/avatars/page.tsx deleted file mode 100644 index b1b1749..0000000 --- a/src/app/(admin)/(ui-elements)/avatars/page.tsx +++ /dev/null @@ -1,126 +0,0 @@ -import ComponentCard from "@/components/common/ComponentCard"; -import PageBreadcrumb from "@/components/common/PageBreadCrumb"; -import Avatar from "@/components/ui/avatar/Avatar"; -import { Metadata } from "next"; -import React from "react"; - -export const metadata: Metadata = { - title: "Next.js Avatars | TailAdmin - Next.js Dashboard Template", - description: - "This is Next.js Avatars page for TailAdmin - Next.js Tailwind CSS Admin Dashboard Template", -}; - -export default function AvatarPage() { - return ( -
- -
- - {/* Default Avatar (No Status) */} -
- - - - - - -
-
- -
- - - - - - -
-
- -
- - - - - - -
-
{" "} - -
- - - - - - -
-
-
-
- ); -} diff --git a/src/app/(admin)/(ui-elements)/badge/page.tsx b/src/app/(admin)/(ui-elements)/badge/page.tsx deleted file mode 100644 index 7dde8dc..0000000 --- a/src/app/(admin)/(ui-elements)/badge/page.tsx +++ /dev/null @@ -1,221 +0,0 @@ -import PageBreadcrumb from "@/components/common/PageBreadCrumb"; -import Badge from "@/components/ui/badge/Badge"; -import { PlusIcon } from "@/icons"; -import { Metadata } from "next"; -import React from "react"; - -export const metadata: Metadata = { - title: "Next.js Badge | TailAdmin - Next.js Dashboard Template", - description: - "This is Next.js Badge page for TailAdmin - Next.js Tailwind CSS Admin Dashboard Template", - // other metadata -}; - -export default function BadgePage() { - return ( -
- -
-
-
-

- With Light Background -

-
-
-
- {/* Light Variant */} - - Primary - - - Success - {" "} - - Error - {" "} - - Warning - {" "} - - Info - - - Light - - - Dark - -
-
-
- -
-
-

- With Solid Background -

-
-
-
- {/* Light Variant */} - - Primary - - - Success - {" "} - - Error - {" "} - - Warning - {" "} - - Info - - - Light - - - Dark - -
-
-
- -
-
-

- Light Background with Left Icon -

-
-
-
- }> - Primary - - }> - Success - {" "} - }> - Error - {" "} - }> - Warning - {" "} - }> - Info - - }> - Light - - }> - Dark - -
-
-
- -
-
-

- Solid Background with Left Icon -

-
-
-
- }> - Primary - - }> - Success - {" "} - }> - Error - {" "} - }> - Warning - {" "} - }> - Info - - }> - Light - - }> - Dark - -
-
-
- -
-
-

- Light Background with Right Icon -

-
-
-
- }> - Primary - - }> - Success - {" "} - }> - Error - {" "} - }> - Warning - {" "} - }> - Info - - }> - Light - - }> - Dark - -
-
-
- -
-
-

- Solid Background with Right Icon -

-
-
-
- }> - Primary - - }> - Success - {" "} - }> - Error - {" "} - }> - Warning - {" "} - }> - Info - - }> - Light - - }> - Dark - -
-
-
-
-
- ); -} diff --git a/src/app/(admin)/(ui-elements)/buttons/page.tsx b/src/app/(admin)/(ui-elements)/buttons/page.tsx deleted file mode 100644 index 77feb50..0000000 --- a/src/app/(admin)/(ui-elements)/buttons/page.tsx +++ /dev/null @@ -1,89 +0,0 @@ -import ComponentCard from "@/components/common/ComponentCard"; -import PageBreadcrumb from "@/components/common/PageBreadCrumb"; -import Button from "@/components/ui/button/Button"; -import { BoxIcon } from "@/icons"; -import { Metadata } from "next"; -import React from "react"; - -export const metadata: Metadata = { - title: "Next.js Buttons | TailAdmin - Next.js Dashboard Template", - description: - "This is Next.js Buttons page for TailAdmin - Next.js Tailwind CSS Admin Dashboard Template", -}; - -export default function Buttons() { - return ( -
- -
- {/* Primary Button */} - -
- - -
-
- {/* Primary Button with Start Icon */} - -
- - -
-
{" "} - {/* Primary Button with Start Icon */} - -
- - -
-
- {/* Outline Button */} - -
- {/* Outline Button */} - - -
-
- {/* Outline Button with Start Icon */} - -
- - -
-
{" "} - {/* Outline Button with Start Icon */} - -
- - -
-
-
-
- ); -} diff --git a/src/app/(admin)/(ui-elements)/images/page.tsx b/src/app/(admin)/(ui-elements)/images/page.tsx deleted file mode 100644 index bcdecd1..0000000 --- a/src/app/(admin)/(ui-elements)/images/page.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import ComponentCard from "@/components/common/ComponentCard"; -import PageBreadcrumb from "@/components/common/PageBreadCrumb"; -import ResponsiveImage from "@/components/ui/images/ResponsiveImage"; -import ThreeColumnImageGrid from "@/components/ui/images/ThreeColumnImageGrid"; -import TwoColumnImageGrid from "@/components/ui/images/TwoColumnImageGrid"; -import { Metadata } from "next"; -import React from "react"; - -export const metadata: Metadata = { - title: "Next.js Images | TailAdmin - Next.js Dashboard Template", - description: - "This is Next.js Images page for TailAdmin - Next.js Tailwind CSS Admin Dashboard Template", - // other metadata -}; - -export default function Images() { - return ( -
- -
- - - - - - - - - -
-
- ); -} diff --git a/src/app/(admin)/(ui-elements)/modals/page.tsx b/src/app/(admin)/(ui-elements)/modals/page.tsx deleted file mode 100644 index 4afa0d0..0000000 --- a/src/app/(admin)/(ui-elements)/modals/page.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import PageBreadcrumb from "@/components/common/PageBreadCrumb"; -import DefaultModal from "@/components/example/ModalExample/DefaultModal"; -import FormInModal from "@/components/example/ModalExample/FormInModal"; -import FullScreenModal from "@/components/example/ModalExample/FullScreenModal"; -import ModalBasedAlerts from "@/components/example/ModalExample/ModalBasedAlerts"; -import VerticallyCenteredModal from "@/components/example/ModalExample/VerticallyCenteredModal"; -import { Metadata } from "next"; -import React from "react"; - -export const metadata: Metadata = { - title: "Next.js Modals | TailAdmin - Next.js Dashboard Template", - description: - "This is Next.js Modals page for TailAdmin - Next.js Tailwind CSS Admin Dashboard Template", - // other metadata -}; - -export default function Modals() { - return ( -
- -
- - - - - -
-
- ); -} diff --git a/src/app/(admin)/(ui-elements)/videos/page.tsx b/src/app/(admin)/(ui-elements)/videos/page.tsx deleted file mode 100644 index 08ddb46..0000000 --- a/src/app/(admin)/(ui-elements)/videos/page.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import PageBreadcrumb from "@/components/common/PageBreadCrumb"; -import VideosExample from "@/components/ui/video/VideosExample"; -import { Metadata } from "next"; -import React from "react"; - -export const metadata: Metadata = { - title: "Next.js Videos | TailAdmin - Next.js Dashboard Template", - description: - "This is Next.js Videos page for TailAdmin - Next.js Tailwind CSS Admin Dashboard Template", -}; - -export default function VideoPage() { - return ( -
- - - -
- ); -} diff --git a/src/app/user/(chart)/bar-chart/page.tsx b/src/app/user/(chart)/bar-chart/page.tsx deleted file mode 100644 index 9ae0984..0000000 --- a/src/app/user/(chart)/bar-chart/page.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import BarChartOne from "@/components/charts/bar/BarChartOne"; -import ComponentCard from "@/components/common/ComponentCard"; -import PageBreadcrumb from "@/components/common/PageBreadCrumb"; -import { Metadata } from "next"; -import React from "react"; - -export const metadata: Metadata = { - title: "Next.js Bar Chart | TailAdmin - Next.js Dashboard Template", - description: - "This is Next.js Bar Chart page for TailAdmin - Next.js Tailwind CSS Admin Dashboard Template", -}; - -export default function page() { - return ( -
- -
- - - -
-
- ); -} diff --git a/src/app/user/(chart)/line-chart/page.tsx b/src/app/user/(chart)/line-chart/page.tsx deleted file mode 100644 index 6ab7664..0000000 --- a/src/app/user/(chart)/line-chart/page.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import LineChartOne from "@/components/charts/line/LineChartOne"; -import ComponentCard from "@/components/common/ComponentCard"; -import PageBreadcrumb from "@/components/common/PageBreadCrumb"; -import { Metadata } from "next"; -import React from "react"; - -export const metadata: Metadata = { - title: "Next.js Line Chart | TailAdmin - Next.js Dashboard Template", - description: - "This is Next.js Line Chart page for TailAdmin - Next.js Tailwind CSS Admin Dashboard Template", -}; -export default function LineChart() { - return ( -
- -
- - - -
-
- ); -} diff --git a/src/app/user/account/page.tsx b/src/app/user/account/page.tsx deleted file mode 100644 index 8384d3e..0000000 --- a/src/app/user/account/page.tsx +++ /dev/null @@ -1,129 +0,0 @@ -"use client"; - -import AccountDetails from "@/components/user-profile/AccountDetails"; -import UserInfoCard from "@/components/user-profile/UserInfoCard"; -import UserMetaCard from "@/components/user-profile/UserMetaCard"; -import { UserMetaCardProps } from "@/interface/user"; -import { apiGetCurrentUser } from "@/service/auth"; -import { setUserData } from "@/store/features/userSlice"; -import { useEffect, useState } from "react"; -import { useDispatch, useSelector } from "react-redux"; -import { RootState } from "@/store/store"; -import StickyHeader from "@/components/ui/StickyHeader"; -import { SafeHTMLRenderer } from "@/components/ui/parse/SafeHTMLRenderer"; -import { apiGetCurrentUserApplications } from "@/service/userService"; -import Loading from "@/app/loading"; - -export default function Profile() { - const currentUser = useSelector((state: RootState) => state.user.data); - const dispatch = useDispatch(); - - const [application, setApplication] = useState(null); - const [appLoading, setAppLoading] = useState(false); - - const isHistorian = !!currentUser?.roles?.some( - (role: any) => role.name === "HISTORIAN" - ); - - // Background refresh of user data to ensure eventual consistency - useEffect(() => { - const fetchUser = async () => { - try { - const userData = await apiGetCurrentUser(); - dispatch(setUserData(userData.data)); - } catch (err) { - console.error("Lỗi:", err); - } - }; - fetchUser(); - }, [dispatch]); - - // Fetch applications in parallel immediately if user is a historian - useEffect(() => { - if (isHistorian) { - const fetchApp = async () => { - try { - setAppLoading(true); - const res = await apiGetCurrentUserApplications(); - if (res?.data) { - const approvedApp = - res.data.find((app: any) => app.status === "APPROVED") || - res.data[0]; - setApplication(approvedApp); - } - } catch (err) { - console.error("Lỗi khi tải hồ sơ nhà sử học:", err); - } finally { - setAppLoading(false); - } - }; - fetchApp(); - } - }, [isHistorian]); - - if (!currentUser) { - return ; - } - - const userMetaProps: UserMetaCardProps = { - data: currentUser - ? { - id: currentUser.id, - email: currentUser.email, - profile: currentUser.profile, - roles: currentUser.roles?.map((role) => ({ - id: Number(role.id) || undefined, - name: role.name, - })), - } - : undefined, - status: true, - }; - - // Nếu người dùng có role là HISTORIAN - if (isHistorian) { - return ( -
- -
-
- - - -
- -
- {appLoading ? ( -
-
-
- ) : application ? ( -
- -
- ) : ( -
- Không tìm thấy thông tin hồ sơ nhà sử học. -
- )} -
-
-
- ); - } - - return ( -
-
-

- Thông tin tài khoản -

-
- - - -
-
-
- ); -} diff --git a/src/app/user/page.tsx b/src/app/user/page.tsx index ff75fa0..6e99209 100644 --- a/src/app/user/page.tsx +++ b/src/app/user/page.tsx @@ -1,41 +1,126 @@ -import type { Metadata } from "next"; -import { EcommerceMetrics } from "@/components/ecommerce/EcommerceMetrics"; -import React from "react"; -import MonthlyTarget from "@/components/ecommerce/MonthlyTarget"; -import MonthlySalesChart from "@/components/ecommerce/MonthlySalesChart"; -import StatisticsChart from "@/components/ecommerce/StatisticsChart"; -import RecentOrders from "@/components/ecommerce/RecentOrders"; -import DemographicCard from "@/components/ecommerce/DemographicCard"; +"use client"; -export const metadata: Metadata = { - title: - "Home Page", - description: "This is Dashboard Home for History Web", -}; +import AccountDetails from "@/components/user-profile/AccountDetails"; +import UserInfoCard from "@/components/user-profile/UserInfoCard"; +import UserMetaCard from "@/components/user-profile/UserMetaCard"; +import { UserMetaCardProps } from "@/interface/user"; +import { apiGetCurrentUser } from "@/service/auth"; +import { setUserData } from "@/store/features/userSlice"; +import { useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { RootState } from "@/store/store"; +import StickyHeader from "@/components/ui/StickyHeader"; +import { SafeHTMLRenderer } from "@/components/ui/parse/SafeHTMLRenderer"; +import { apiGetCurrentUserApplications } from "@/service/userService"; +import Loading from "@/app/loading"; + +export default function Profile() { + const currentUser = useSelector((state: RootState) => state.user.data); + const dispatch = useDispatch(); + + const [application, setApplication] = useState(null); + const [appLoading, setAppLoading] = useState(false); + + const isHistorian = !!currentUser?.roles?.some( + (role: any) => role.name === "HISTORIAN" + ); + + useEffect(() => { + const fetchUser = async () => { + try { + const userData = await apiGetCurrentUser(); + dispatch(setUserData(userData.data)); + } catch (err) { + console.error("Lỗi:", err); + } + }; + fetchUser(); + }, [dispatch]); + + useEffect(() => { + if (isHistorian) { + const fetchApp = async () => { + try { + setAppLoading(true); + const res = await apiGetCurrentUserApplications(); + if (res?.data) { + const approvedApp = + res.data.find((app: any) => app.status === "APPROVED") || + res.data[0]; + setApplication(approvedApp); + } + } catch (err) { + console.error("Lỗi khi tải hồ sơ nhà sử học:", err); + } finally { + setAppLoading(false); + } + }; + fetchApp(); + } + }, [isHistorian]); + + if (!currentUser) { + return ; + } + + const userMetaProps: UserMetaCardProps = { + data: currentUser + ? { + id: currentUser.id, + email: currentUser.email, + profile: currentUser.profile, + roles: currentUser.roles?.map((role) => ({ + id: Number(role.id) || undefined, + name: role.name, + })), + } + : undefined, + status: true, + }; + + // Nếu người dùng có role là HISTORIAN + if (isHistorian) { + return ( +
+ +
+
+ + + +
+ +
+ {appLoading ? ( +
+
+
+ ) : application ? ( +
+ +
+ ) : ( +
+ Không tìm thấy thông tin hồ sơ nhà sử học. +
+ )} +
+
+
+ ); + } -export default function Ecommerce() { return ( -
-
- - - -
- -
- -
- -
- -
- -
- -
- -
- +
+
+

+ Thông tin tài khoản +

+
+ + + +
); diff --git a/src/components/calendar/Calendar.tsx b/src/components/calendar/Calendar.tsx deleted file mode 100644 index b3bb58c..0000000 --- a/src/components/calendar/Calendar.tsx +++ /dev/null @@ -1,293 +0,0 @@ -"use client"; -import React, { useState, useRef, useEffect } from "react"; -import FullCalendar from "@fullcalendar/react"; -import dayGridPlugin from "@fullcalendar/daygrid"; -import timeGridPlugin from "@fullcalendar/timegrid"; -import interactionPlugin from "@fullcalendar/interaction"; -import { - EventInput, - DateSelectArg, - EventClickArg, - EventContentArg, -} from "@fullcalendar/core"; -import { useModal } from "@/hooks/useModal"; -import { Modal } from "@/components/ui/modal"; -import { newId } from "@/uhm/lib/utils/id"; - -interface CalendarEvent extends EventInput { - extendedProps: { - calendar: string; - }; -} - -const Calendar: React.FC = () => { - const [selectedEvent, setSelectedEvent] = useState( - null - ); - const [eventTitle, setEventTitle] = useState(""); - const [eventStartDate, setEventStartDate] = useState(""); - const [eventEndDate, setEventEndDate] = useState(""); - const [eventLevel, setEventLevel] = useState(""); - const [events, setEvents] = useState([]); - const calendarRef = useRef(null); - const { isOpen, openModal, closeModal } = useModal(); - - const calendarsEvents = { - Danger: "danger", - Success: "success", - Primary: "primary", - Warning: "warning", - }; - - useEffect(() => { - // Initialize with some events - setEvents([ - { - id: "1", - title: "Event Conf.", - start: new Date().toISOString().split("T")[0], - extendedProps: { calendar: "Danger" }, - }, - { - id: "2", - title: "Meeting", - start: new Date(Date.now() + 86400000).toISOString().split("T")[0], - extendedProps: { calendar: "Success" }, - }, - { - id: "3", - title: "Workshop", - start: new Date(Date.now() + 172800000).toISOString().split("T")[0], - end: new Date(Date.now() + 259200000).toISOString().split("T")[0], - extendedProps: { calendar: "Primary" }, - }, - ]); - }, []); - - const handleDateSelect = (selectInfo: DateSelectArg) => { - resetModalFields(); - setEventStartDate(selectInfo.startStr); - setEventEndDate(selectInfo.endStr || selectInfo.startStr); - openModal(); - }; - - const handleEventClick = (clickInfo: EventClickArg) => { - const event = clickInfo.event; - setSelectedEvent({ - id: event.id, - title: event.title, - start: event.startStr, - end: event.endStr, - extendedProps: { - calendar: event.extendedProps.calendar, - }, - } as CalendarEvent); - - setEventTitle(event.title); - setEventStartDate(event.start?.toISOString().split("T")[0] || ""); - setEventEndDate(event.end?.toISOString().split("T")[0] || ""); - setEventLevel(event.extendedProps.calendar); - openModal(); - }; - - const handleAddOrUpdateEvent = () => { - if (selectedEvent) { - // Update existing event - setEvents((prevEvents) => - prevEvents.map((event) => - event.id === selectedEvent.id - ? { - ...event, - title: eventTitle, - start: eventStartDate, - end: eventEndDate, - extendedProps: { calendar: eventLevel }, - } - : event - ) - ); - } else { - // Add new event - const newEvent: CalendarEvent = { - id: newId(), - title: eventTitle, - start: eventStartDate, - end: eventEndDate, - allDay: true, - extendedProps: { calendar: eventLevel }, - }; - setEvents((prevEvents) => [...prevEvents, newEvent]); - } - closeModal(); - resetModalFields(); - }; - - const resetModalFields = () => { - setEventTitle(""); - setEventStartDate(""); - setEventEndDate(""); - setEventLevel(""); - setSelectedEvent(null); - }; - - return ( -
-
- -
- -
-
-
- {selectedEvent ? "Edit Event" : "Add Event"} -
-

- Plan your next big moment: schedule or edit an event to stay on - track -

-
-
-
-
- - setEventTitle(e.target.value)} - className="dark:bg-dark-900 h-11 w-full rounded-lg border border-gray-300 bg-transparent px-4 py-2.5 text-sm text-gray-800 shadow-theme-xs placeholder:text-gray-400 focus:border-brand-300 focus:outline-hidden focus:ring-3 focus:ring-brand-500/10 dark:border-gray-700 dark:bg-gray-900 dark:text-white/90 dark:placeholder:text-white/30 dark:focus:border-brand-800" - /> -
-
-
- -
- {Object.entries(calendarsEvents).map(([key, value]) => ( -
-
- -
-
- ))} -
-
- -
- -
- setEventStartDate(e.target.value)} - className="dark:bg-dark-900 h-11 w-full appearance-none rounded-lg border border-gray-300 bg-transparent bg-none px-4 py-2.5 pl-4 pr-11 text-sm text-gray-800 shadow-theme-xs placeholder:text-gray-400 focus:border-brand-300 focus:outline-hidden focus:ring-3 focus:ring-brand-500/10 dark:border-gray-700 dark:bg-gray-900 dark:text-white/90 dark:placeholder:text-white/30 dark:focus:border-brand-800" - /> -
-
- -
- -
- setEventEndDate(e.target.value)} - className="dark:bg-dark-900 h-11 w-full appearance-none rounded-lg border border-gray-300 bg-transparent bg-none px-4 py-2.5 pl-4 pr-11 text-sm text-gray-800 shadow-theme-xs placeholder:text-gray-400 focus:border-brand-300 focus:outline-hidden focus:ring-3 focus:ring-brand-500/10 dark:border-gray-700 dark:bg-gray-900 dark:text-white/90 dark:placeholder:text-white/30 dark:focus:border-brand-800" - /> -
-
-
-
- - -
-
-
-
- ); -}; - -const renderEventContent = (eventInfo: EventContentArg) => { - const colorClass = `fc-bg-${eventInfo.event.extendedProps.calendar.toLowerCase()}`; - return ( -
-
-
{eventInfo.timeText}
-
{eventInfo.event.title}
-
- ); -}; - -export default Calendar; diff --git a/src/components/charts/bar/BarChartOne.tsx b/src/components/charts/bar/BarChartOne.tsx deleted file mode 100644 index e373a7a..0000000 --- a/src/components/charts/bar/BarChartOne.tsx +++ /dev/null @@ -1,110 +0,0 @@ -"use client"; -import React from "react"; - -import { ApexOptions } from "apexcharts"; - -import dynamic from "next/dynamic"; -// Dynamically import the ReactApexChart component -const ReactApexChart = dynamic(() => import("react-apexcharts"), { - ssr: false, -}); - -export default function BarChartOne() { - const options: ApexOptions = { - colors: ["#465fff"], - chart: { - fontFamily: "Outfit, sans-serif", - type: "bar", - height: 180, - toolbar: { - show: false, - }, - }, - plotOptions: { - bar: { - horizontal: false, - columnWidth: "39%", - borderRadius: 5, - borderRadiusApplication: "end", - }, - }, - dataLabels: { - enabled: false, - }, - stroke: { - show: true, - width: 4, - colors: ["transparent"], - }, - xaxis: { - categories: [ - "Jan", - "Feb", - "Mar", - "Apr", - "May", - "Jun", - "Jul", - "Aug", - "Sep", - "Oct", - "Nov", - "Dec", - ], - axisBorder: { - show: false, - }, - axisTicks: { - show: false, - }, - }, - legend: { - show: true, - position: "top", - horizontalAlign: "left", - fontFamily: "Outfit", - }, - yaxis: { - title: { - text: undefined, - }, - }, - grid: { - yaxis: { - lines: { - show: true, - }, - }, - }, - fill: { - opacity: 1, - }, - - tooltip: { - x: { - show: false, - }, - y: { - formatter: (val: number) => `${val}`, - }, - }, - }; - const series = [ - { - name: "Sales", - data: [168, 385, 201, 298, 187, 195, 291, 110, 215, 390, 280, 112], - }, - ]; - return ( -
-
- -
-
- ); -} diff --git a/src/components/charts/line/LineChartOne.tsx b/src/components/charts/line/LineChartOne.tsx deleted file mode 100644 index 94d39b3..0000000 --- a/src/components/charts/line/LineChartOne.tsx +++ /dev/null @@ -1,133 +0,0 @@ -"use client"; -import React from "react"; - -import { ApexOptions } from "apexcharts"; - -import dynamic from "next/dynamic"; -// Dynamically import the ReactApexChart component -const ReactApexChart = dynamic(() => import("react-apexcharts"), { - ssr: false, -}); - -export default function LineChartOne() { - const options: ApexOptions = { - legend: { - show: false, // Hide legend - position: "top", - horizontalAlign: "left", - }, - colors: ["#465FFF", "#9CB9FF"], // Define line colors - chart: { - fontFamily: "Outfit, sans-serif", - height: 310, - type: "line", // Set the chart type to 'line' - toolbar: { - show: false, // Hide chart toolbar - }, - }, - stroke: { - curve: "straight", // Define the line style (straight, smooth, or step) - width: [2, 2], // Line width for each dataset - }, - - fill: { - type: "gradient", - gradient: { - opacityFrom: 0.55, - opacityTo: 0, - }, - }, - markers: { - size: 0, // Size of the marker points - strokeColors: "#fff", // Marker border color - strokeWidth: 2, - hover: { - size: 6, // Marker size on hover - }, - }, - grid: { - xaxis: { - lines: { - show: false, // Hide grid lines on x-axis - }, - }, - yaxis: { - lines: { - show: true, // Show grid lines on y-axis - }, - }, - }, - dataLabels: { - enabled: false, // Disable data labels - }, - tooltip: { - enabled: true, // Enable tooltip - x: { - format: "dd MMM yyyy", // Format for x-axis tooltip - }, - }, - xaxis: { - type: "category", // Category-based x-axis - categories: [ - "Jan", - "Feb", - "Mar", - "Apr", - "May", - "Jun", - "Jul", - "Aug", - "Sep", - "Oct", - "Nov", - "Dec", - ], - axisBorder: { - show: false, // Hide x-axis border - }, - axisTicks: { - show: false, // Hide x-axis ticks - }, - tooltip: { - enabled: false, // Disable tooltip for x-axis points - }, - }, - yaxis: { - labels: { - style: { - fontSize: "12px", // Adjust font size for y-axis labels - colors: ["#6B7280"], // Color of the labels - }, - }, - title: { - text: "", // Remove y-axis title - style: { - fontSize: "0px", - }, - }, - }, - }; - - const series = [ - { - name: "Sales", - data: [180, 190, 170, 160, 175, 165, 170, 205, 230, 210, 240, 235], - }, - { - name: "Revenue", - data: [40, 30, 50, 40, 55, 40, 70, 100, 110, 120, 150, 140], - }, - ]; - return ( -
-
- -
-
- ); -} diff --git a/src/components/common/ChartTab.tsx b/src/components/common/ChartTab.tsx deleted file mode 100644 index d2f5820..0000000 --- a/src/components/common/ChartTab.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import React, { useState } from "react"; - -const ChartTab: React.FC = () => { - const [selected, setSelected] = useState< - "optionOne" | "optionTwo" | "optionThree" - >("optionOne"); - - const getButtonClass = (option: "optionOne" | "optionTwo" | "optionThree") => - selected === option - ? "shadow-theme-xs text-gray-900 dark:text-white bg-white dark:bg-gray-800" - : "text-gray-500 dark:text-gray-400"; - - return ( -
- - - - - -
- ); -}; - -export default ChartTab; diff --git a/src/components/ecommerce/CountryMap.tsx b/src/components/ecommerce/CountryMap.tsx deleted file mode 100644 index 589df37..0000000 --- a/src/components/ecommerce/CountryMap.tsx +++ /dev/null @@ -1,123 +0,0 @@ -import React from "react"; -// import { VectorMap } from "@react-jvectormap/core"; -import { worldMill } from "@react-jvectormap/world"; -import dynamic from "next/dynamic"; - -const VectorMap = dynamic( - () => import("@react-jvectormap/core").then((mod) => mod.VectorMap), - { ssr: false } -); - -// Define the component props -interface CountryMapProps { - mapColor?: string; -} - -type MarkerStyle = { - initial: { - fill: string; - r: number; // Radius for markers - }; -}; - -type Marker = { - latLng: [number, number]; - name: string; - style?: { - fill: string; - borderWidth: number; - borderColor: string; - stroke?: string; - strokeOpacity?: number; - }; -}; - -const CountryMap: React.FC = ({ mapColor }) => { - return ( - - ); -}; - -export default CountryMap; diff --git a/src/components/ecommerce/DemographicCard.tsx b/src/components/ecommerce/DemographicCard.tsx deleted file mode 100644 index f2b552b..0000000 --- a/src/components/ecommerce/DemographicCard.tsx +++ /dev/null @@ -1,131 +0,0 @@ -"use client"; -import Image from "next/image"; - -import CountryMap from "./CountryMap"; -import { useState } from "react"; -import { MoreDotIcon } from "@/icons"; -import { Dropdown } from "../ui/dropdown/Dropdown"; -import { DropdownItem } from "../ui/dropdown/DropdownItem"; - -export default function DemographicCard() { - const [isOpen, setIsOpen] = useState(false); - - function toggleDropdown() { - setIsOpen(!isOpen); - } - - function closeDropdown() { - setIsOpen(false); - } - - return ( -
-
-
-

- Customers Demographic -

-

- Number of customer based on country -

-
- -
- - - - View More - - - Delete - - -
-
-
-
- -
-
- -
-
-
-
- usa -
-
-

- USA -

- - 2,379 Customers - -
-
- -
-
-
-
-

- 79% -

-
-
- -
-
-
- france -
-
-

- France -

- - 589 Customers - -
-
- -
-
-
-
-

- 23% -

-
-
-
-
- ); -} diff --git a/src/components/ecommerce/EcommerceMetrics.tsx b/src/components/ecommerce/EcommerceMetrics.tsx deleted file mode 100644 index 58ab6c1..0000000 --- a/src/components/ecommerce/EcommerceMetrics.tsx +++ /dev/null @@ -1,56 +0,0 @@ -"use client"; -import React from "react"; -import Badge from "../ui/badge/Badge"; -import { ArrowDownIcon, ArrowUpIcon, BoxIconLine, GroupIcon } from "@/icons"; - -export const EcommerceMetrics = () => { - return ( -
- {/* */} -
-
- -
- -
-
- - Customers - -

- 3,782 -

-
- - - 11.01% - -
-
- {/* */} - - {/* */} -
-
- -
-
-
- - Orders - -

- 5,359 -

-
- - - - 9.05% - -
-
- {/* */} -
- ); -}; diff --git a/src/components/ecommerce/MonthlySalesChart.tsx b/src/components/ecommerce/MonthlySalesChart.tsx deleted file mode 100644 index ed387ce..0000000 --- a/src/components/ecommerce/MonthlySalesChart.tsx +++ /dev/null @@ -1,154 +0,0 @@ -"use client"; -import { ApexOptions } from "apexcharts"; -import dynamic from "next/dynamic"; -import { MoreDotIcon } from "@/icons"; -import { DropdownItem } from "../ui/dropdown/DropdownItem"; -import { useState } from "react"; -import { Dropdown } from "../ui/dropdown/Dropdown"; - -// Dynamically import the ReactApexChart component -const ReactApexChart = dynamic(() => import("react-apexcharts"), { - ssr: false, -}); - -export default function MonthlySalesChart() { - const options: ApexOptions = { - colors: ["#465fff"], - chart: { - fontFamily: "Outfit, sans-serif", - type: "bar", - height: 180, - toolbar: { - show: false, - }, - }, - plotOptions: { - bar: { - horizontal: false, - columnWidth: "39%", - borderRadius: 5, - borderRadiusApplication: "end", - }, - }, - dataLabels: { - enabled: false, - }, - stroke: { - show: true, - width: 4, - colors: ["transparent"], - }, - xaxis: { - categories: [ - "Jan", - "Feb", - "Mar", - "Apr", - "May", - "Jun", - "Jul", - "Aug", - "Sep", - "Oct", - "Nov", - "Dec", - ], - axisBorder: { - show: false, - }, - axisTicks: { - show: false, - }, - }, - legend: { - show: true, - position: "top", - horizontalAlign: "left", - fontFamily: "Outfit", - }, - yaxis: { - title: { - text: undefined, - }, - }, - grid: { - yaxis: { - lines: { - show: true, - }, - }, - }, - fill: { - opacity: 1, - }, - - tooltip: { - x: { - show: false, - }, - y: { - formatter: (val: number) => `${val}`, - }, - }, - }; - const series = [ - { - name: "Sales", - data: [168, 385, 201, 298, 187, 195, 291, 110, 215, 390, 280, 112], - }, - ]; - const [isOpen, setIsOpen] = useState(false); - - function toggleDropdown() { - setIsOpen(!isOpen); - } - - function closeDropdown() { - setIsOpen(false); - } - - return ( -
-
-

- Monthly Sales -

- -
- - - - View More - - - Delete - - -
-
- -
-
- -
-
-
- ); -} diff --git a/src/components/ecommerce/MonthlyTarget.tsx b/src/components/ecommerce/MonthlyTarget.tsx deleted file mode 100644 index d4f66db..0000000 --- a/src/components/ecommerce/MonthlyTarget.tsx +++ /dev/null @@ -1,209 +0,0 @@ -"use client"; -// import Chart from "react-apexcharts"; -import { ApexOptions } from "apexcharts"; - -import dynamic from "next/dynamic"; -import { Dropdown } from "../ui/dropdown/Dropdown"; -import { MoreDotIcon } from "@/icons"; -import { useState } from "react"; -import { DropdownItem } from "../ui/dropdown/DropdownItem"; -// Dynamically import the ReactApexChart component -const ReactApexChart = dynamic(() => import("react-apexcharts"), { - ssr: false, -}); - -export default function MonthlyTarget() { - const series = [75.55]; - const options: ApexOptions = { - colors: ["#465FFF"], - chart: { - fontFamily: "Outfit, sans-serif", - type: "radialBar", - height: 330, - sparkline: { - enabled: true, - }, - }, - plotOptions: { - radialBar: { - startAngle: -85, - endAngle: 85, - hollow: { - size: "80%", - }, - track: { - background: "#E4E7EC", - strokeWidth: "100%", - margin: 5, // margin is in pixels - }, - dataLabels: { - name: { - show: false, - }, - value: { - fontSize: "36px", - fontWeight: "600", - offsetY: -40, - color: "#1D2939", - formatter: function (val) { - return val + "%"; - }, - }, - }, - }, - }, - fill: { - type: "solid", - colors: ["#465FFF"], - }, - stroke: { - lineCap: "round", - }, - labels: ["Progress"], - }; - - const [isOpen, setIsOpen] = useState(false); - - function toggleDropdown() { - setIsOpen(!isOpen); - } - - function closeDropdown() { - setIsOpen(false); - } - - return ( -
-
-
-
-

- Monthly Target -

-

- Target you’ve set for each month -

-
-
- - - - View More - - - Delete - - -
-
-
-
- -
- - - +10% - -
-

- You earn $3287 today, it's higher than last month. Keep up your - good work! -

-
- -
-
-

- Target -

-

- $20K - - - -

-
- -
- -
-

- Revenue -

-

- $20K - - - -

-
- -
- -
-

- Today -

-

- $20K - - - -

-
-
-
- ); -} diff --git a/src/components/ecommerce/RecentOrders.tsx b/src/components/ecommerce/RecentOrders.tsx deleted file mode 100644 index d06a073..0000000 --- a/src/components/ecommerce/RecentOrders.tsx +++ /dev/null @@ -1,211 +0,0 @@ -import { - Table, - TableBody, - TableCell, - TableHeader, - TableRow, -} from "../ui/table"; -import Badge from "../ui/badge/Badge"; -import Image from "next/image"; - -// Define the TypeScript interface for the table rows -interface Product { - id: number; // Unique identifier for each product - name: string; // Product name - variants: string; // Number of variants (e.g., "1 Variant", "2 Variants") - category: string; // Category of the product - price: string; // Price of the product (as a string with currency symbol) - // status: string; // Status of the product - image: string; // URL or path to the product image - status: "Delivered" | "Pending" | "Canceled"; // Status of the product -} - -// Define the table data using the interface -const tableData: Product[] = [ - { - id: 1, - name: "MacBook Pro 13”", - variants: "2 Variants", - category: "Laptop", - price: "$2399.00", - status: "Delivered", - image: "/images/product/product-01.jpg", // Replace with actual image URL - }, - { - id: 2, - name: "Apple Watch Ultra", - variants: "1 Variant", - category: "Watch", - price: "$879.00", - status: "Pending", - image: "/images/product/product-02.jpg", // Replace with actual image URL - }, - { - id: 3, - name: "iPhone 15 Pro Max", - variants: "2 Variants", - category: "SmartPhone", - price: "$1869.00", - status: "Delivered", - image: "/images/product/product-03.jpg", // Replace with actual image URL - }, - { - id: 4, - name: "iPad Pro 3rd Gen", - variants: "2 Variants", - category: "Electronics", - price: "$1699.00", - status: "Canceled", - image: "/images/product/product-04.jpg", // Replace with actual image URL - }, - { - id: 5, - name: "AirPods Pro 2nd Gen", - variants: "1 Variant", - category: "Accessories", - price: "$240.00", - status: "Delivered", - image: "/images/product/product-05.jpg", // Replace with actual image URL - }, -]; - -export default function RecentOrders() { - return ( -
-
-
-

- Recent Orders -

-
- -
- - -
-
-
- - {/* Table Header */} - - - - Products - - - Category - - - Price - - - Status - - - - - {/* Table Body */} - - - {tableData.map((product) => ( - - -
-
- -
-
-

- {product.name} -

- - {product.variants} - -
-
-
- - {product.price} - - - {product.category} - - - - {product.status} - - -
- ))} -
-
-
-
- ); -} diff --git a/src/components/ecommerce/StatisticsChart.tsx b/src/components/ecommerce/StatisticsChart.tsx deleted file mode 100644 index ee91bf1..0000000 --- a/src/components/ecommerce/StatisticsChart.tsx +++ /dev/null @@ -1,181 +0,0 @@ -"use client"; -import { useEffect, useRef } from "react"; -import dynamic from "next/dynamic"; -import { ApexOptions } from "apexcharts"; -import flatpickr from "flatpickr"; -import "flatpickr/dist/flatpickr.css"; -import ChartTab from "../common/ChartTab"; -import { CalenderIcon } from "../../icons"; - -const Chart = dynamic(() => import("react-apexcharts"), { ssr: false }); - -export default function StatisticsChart() { - const datePickerRef = useRef(null); - - useEffect(() => { - if (!datePickerRef.current) return; - - const today = new Date(); - const sevenDaysAgo = new Date(); - sevenDaysAgo.setDate(today.getDate() - 6); - - const fp = flatpickr(datePickerRef.current, { - mode: "range", - static: true, - monthSelectorType: "static", - dateFormat: "M d", - defaultDate: [sevenDaysAgo, today], - clickOpens: true, - prevArrow: - '', - nextArrow: - '', - }); - - return () => { - if (!Array.isArray(fp)) { - fp.destroy(); - } - }; - }, []); - - const options: ApexOptions = { - legend: { - show: false, // Hide legend - position: "top", - horizontalAlign: "left", - }, - colors: ["#465FFF", "#9CB9FF"], // Define line colors - chart: { - fontFamily: "Outfit, sans-serif", - height: 310, - type: "line", // Set the chart type to 'line' - toolbar: { - show: false, // Hide chart toolbar - }, - }, - stroke: { - curve: "straight", // Define the line style (straight, smooth, or step) - width: [2, 2], // Line width for each dataset - }, - - fill: { - type: "gradient", - gradient: { - opacityFrom: 0.55, - opacityTo: 0, - }, - }, - markers: { - size: 0, // Size of the marker points - strokeColors: "#fff", // Marker border color - strokeWidth: 2, - hover: { - size: 6, // Marker size on hover - }, - }, - grid: { - xaxis: { - lines: { - show: false, // Hide grid lines on x-axis - }, - }, - yaxis: { - lines: { - show: true, // Show grid lines on y-axis - }, - }, - }, - dataLabels: { - enabled: false, // Disable data labels - }, - tooltip: { - enabled: true, // Enable tooltip - x: { - format: "dd MMM yyyy", // Format for x-axis tooltip - }, - }, - xaxis: { - type: "category", // Category-based x-axis - categories: [ - "Jan", - "Feb", - "Mar", - "Apr", - "May", - "Jun", - "Jul", - "Aug", - "Sep", - "Oct", - "Nov", - "Dec", - ], - axisBorder: { - show: false, // Hide x-axis border - }, - axisTicks: { - show: false, // Hide x-axis ticks - }, - tooltip: { - enabled: false, // Disable tooltip for x-axis points - }, - }, - yaxis: { - labels: { - style: { - fontSize: "12px", // Adjust font size for y-axis labels - colors: ["#6B7280"], // Color of the labels - }, - }, - title: { - text: "", // Remove y-axis title - style: { - fontSize: "0px", - }, - }, - }, - }; - - const series = [ - { - name: "Sales", - data: [180, 190, 170, 160, 175, 165, 170, 205, 230, 210, 240, 235], - }, - { - name: "Revenue", - data: [40, 30, 50, 40, 55, 40, 70, 100, 110, 120, 150, 140], - }, - ]; - return ( -
-
-
-

- Statistics -

-

- Target you've set for each month -

-
-
- -
- - -
-
-
- -
-
- -
-
-
- ); -} \ No newline at end of file diff --git a/src/components/example/ModalExample/DefaultModal.tsx b/src/components/example/ModalExample/DefaultModal.tsx deleted file mode 100644 index c017f01..0000000 --- a/src/components/example/ModalExample/DefaultModal.tsx +++ /dev/null @@ -1,53 +0,0 @@ -"use client"; -import React from "react"; -import ComponentCard from "../../common/ComponentCard"; - -import { Modal } from "../../ui/modal"; -import Button from "../../ui/button/Button"; -import { useModal } from "@/hooks/useModal"; - -export default function DefaultModal() { - const { isOpen, openModal, closeModal } = useModal(); - const handleSave = () => { - // Handle save logic here - console.log("Saving changes..."); - closeModal(); - }; - return ( -
- - - -

- Modal Heading -

-

- Lorem ipsum dolor sit amet, consectetur adipiscing elit. - Pellentesque euismod est quis mauris lacinia pharetra. Sed a ligula - ac odio condimentum aliquet a nec nulla. Aliquam bibendum ex sit - amet ipsum rutrum feugiat ultrices enim quam. -

-

- Lorem ipsum dolor sit amet, consectetur adipiscing elit. - Pellentesque euismod est quis mauris lacinia pharetra. Sed a ligula - ac odio. -

-
- - -
-
-
-
- ); -} diff --git a/src/components/example/ModalExample/FormInModal.tsx b/src/components/example/ModalExample/FormInModal.tsx deleted file mode 100644 index 9b6c4e0..0000000 --- a/src/components/example/ModalExample/FormInModal.tsx +++ /dev/null @@ -1,71 +0,0 @@ -"use client"; -import React from "react"; -import ComponentCard from "../../common/ComponentCard"; -import Button from "../../ui/button/Button"; -import { Modal } from "../../ui/modal"; -import Label from "../../form/Label"; -import Input from "../../form/input/InputField"; -import { useModal } from "@/hooks/useModal"; - -export default function FormInModal() { - const { isOpen, openModal, closeModal } = useModal(); - const handleSave = () => { - // Handle save logic here - console.log("Saving changes..."); - closeModal(); - }; - return ( - - - -
-

- Personal Information -

- -
-
- - -
- -
- - -
- -
- - -
- -
- - -
- -
- - -
-
- -
- - -
-
-
-
- ); -} diff --git a/src/components/example/ModalExample/FullScreenModal.tsx b/src/components/example/ModalExample/FullScreenModal.tsx deleted file mode 100644 index b51f69b..0000000 --- a/src/components/example/ModalExample/FullScreenModal.tsx +++ /dev/null @@ -1,66 +0,0 @@ -"use client"; -import { useModal } from "@/hooks/useModal"; -import ComponentCard from "../../common/ComponentCard"; - -import Button from "../../ui/button/Button"; -import { Modal } from "../../ui/modal"; - -export default function FullScreenModal() { - const { - isOpen: isFullscreenModalOpen, - openModal: openFullscreenModal, - closeModal: closeFullscreenModal, - } = useModal(); - const handleSave = () => { - // Handle save logic here - console.log("Saving changes..."); - closeFullscreenModal(); - }; - return ( - - - -
-
-

- Modal Heading -

-

- Lorem ipsum dolor sit amet, consectetur adipiscing elit. - Pellentesque euismod est quis mauris lacinia pharetra. Sed a - ligula ac odio condimentum aliquet a nec nulla. Aliquam bibendum - ex sit amet ipsum rutrum feugiat ultrices enim quam. -

-

- Lorem ipsum dolor sit amet, consectetur adipiscing elit. - Pellentesque euismod est quis mauris lacinia pharetra. Sed a - ligula ac odio condimentum aliquet a nec nulla. Aliquam bibendum - ex sit amet ipsum rutrum feugiat ultrices enim quam odio - condimentum aliquet a nec nulla pellentesque euismod est quis - mauris lacinia pharetra. -

-

- Lorem ipsum dolor sit amet, consectetur adipiscing elit. - Pellentesque euismod est quis mauris lacinia pharetra. -

-
-
- - -
-
-
-
- ); -} diff --git a/src/components/example/ModalExample/ModalBasedAlerts.tsx b/src/components/example/ModalExample/ModalBasedAlerts.tsx deleted file mode 100644 index 7a1c560..0000000 --- a/src/components/example/ModalExample/ModalBasedAlerts.tsx +++ /dev/null @@ -1,282 +0,0 @@ -"use client"; -import React from "react"; -import ComponentCard from "../../common/ComponentCard"; - -import { Modal } from "../../ui/modal"; -import { useModal } from "@/hooks/useModal"; - -export default function ModalBasedAlerts() { - const successModal = useModal(); - const infoModal = useModal(); - const warningModal = useModal(); - const errorModal = useModal(); - return ( - -
- - - - -
- {/* Success Modal */} - -
-
- - - - - - - - - -
-

- Well Done! -

-

- Lorem ipsum dolor sit amet consectetur. Feugiat ipsum libero tempor - felis risus nisi non. Quisque eu ut tempor curabitur. -

- -
- -
-
-
- {/* Info Modal */} - -
-
- - - - - - - - - -
- -

- Information Alert! -

-

- Lorem ipsum dolor sit amet consectetur. Feugiat ipsum libero tempor - felis risus nisi non. Quisque eu ut tempor curabitur. -

- -
- -
-
-
- {/* Warning Modal */} - -
-
- - - - - - - - - -
- -

- Warning Alert! -

-

- Lorem ipsum dolor sit amet consectetur. Feugiat ipsum libero tempor - felis risus nisi non. Quisque eu ut tempor curabitur. -

- -
- -
-
-
- {/* Error Modal */} - -
-
- - - - - - - - - -
- -

- Danger Alert! -

-

- Lorem ipsum dolor sit amet consectetur. Feugiat ipsum libero tempor - felis risus nisi non. Quisque eu ut tempor curabitur. -

- -
- -
-
-
-
- ); -} diff --git a/src/components/example/ModalExample/VerticallyCenteredModal.tsx b/src/components/example/ModalExample/VerticallyCenteredModal.tsx deleted file mode 100644 index 2ec90a7..0000000 --- a/src/components/example/ModalExample/VerticallyCenteredModal.tsx +++ /dev/null @@ -1,47 +0,0 @@ -"use client"; -import React from "react"; -import ComponentCard from "../../common/ComponentCard"; -import Button from "../../ui/button/Button"; -import { Modal } from "../../ui/modal"; -import { useModal } from "@/hooks/useModal"; - -export default function VerticallyCenteredModal() { - const { isOpen, openModal, closeModal } = useModal(); - const handleSave = () => { - // Handle save logic here - console.log("Saving changes..."); - closeModal(); - }; - return ( - - - -
-

- All Done! Success Confirmed -

-

- Lorem ipsum dolor sit amet, consectetur adipiscing elit. - Pellentesque euismod est quis mauris lacinia pharetra. -

- -
- - -
-
-
-
- ); -} diff --git a/src/components/form/Form.tsx b/src/components/form/Form.tsx deleted file mode 100644 index 0530a6a..0000000 --- a/src/components/form/Form.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import React, { FC, ReactNode, FormEvent } from "react"; - -interface FormProps { - onSubmit: (event: FormEvent) => void; - children: ReactNode; - className?: string; -} - -const Form: FC = ({ onSubmit, children, className }) => { - return ( -
{ - event.preventDefault(); // Prevent default form submission - onSubmit(event); - }} - className={` ${className}`} // Default spacing between form fields - > - {children} -
- ); -}; - -export default Form; diff --git a/src/components/form/MultiSelect.tsx b/src/components/form/MultiSelect.tsx deleted file mode 100644 index 49651b5..0000000 --- a/src/components/form/MultiSelect.tsx +++ /dev/null @@ -1,166 +0,0 @@ -import React, { useState } from "react"; - -interface Option { - value: string; - text: string; - selected: boolean; -} - -interface MultiSelectProps { - label: string; - options: Option[]; - defaultSelected?: string[]; - onChange?: (selected: string[]) => void; - disabled?: boolean; -} - -const MultiSelect: React.FC = ({ - label, - options, - defaultSelected = [], - onChange, - disabled = false, -}) => { - const [selectedOptions, setSelectedOptions] = - useState(defaultSelected); - const [isOpen, setIsOpen] = useState(false); - - const toggleDropdown = () => { - if (disabled) return; - setIsOpen((prev) => !prev); - }; - - const handleSelect = (optionValue: string) => { - const newSelectedOptions = selectedOptions.includes(optionValue) - ? selectedOptions.filter((value) => value !== optionValue) - : [...selectedOptions, optionValue]; - - setSelectedOptions(newSelectedOptions); - if (onChange) onChange(newSelectedOptions); - }; - - const removeOption = (index: number, value: string) => { - const newSelectedOptions = selectedOptions.filter((opt) => opt !== value); - setSelectedOptions(newSelectedOptions); - if (onChange) onChange(newSelectedOptions); - }; - - const selectedValuesText = selectedOptions.map( - (value) => options.find((option) => option.value === value)?.text || "" - ); - - return ( -
- - -
-
-
-
-
- {selectedValuesText.length > 0 ? ( - selectedValuesText.map((text, index) => ( -
- {text} -
-
- removeOption(index, selectedOptions[index]) - } - className="pl-2 text-gray-500 cursor-pointer group-hover:text-gray-400 dark:text-gray-400" - > - - - -
-
-
- )) - ) : ( - - )} -
-
- -
-
-
- - {isOpen && ( -
e.stopPropagation()} - > -
- {options.map((option, index) => ( -
-
handleSelect(option.value)} - > -
-
- {option.text} -
-
-
-
- ))} -
-
- )} -
-
-
- ); -}; - -export default MultiSelect; diff --git a/src/components/form/Select.tsx b/src/components/form/Select.tsx deleted file mode 100644 index b32c839..0000000 --- a/src/components/form/Select.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import React, { useState } from "react"; - -interface Option { - value: string; - label: string; -} - -interface SelectProps { - options: Option[]; - placeholder?: string; - onChange: (value: string) => void; - className?: string; - defaultValue?: string; -} - -const Select: React.FC = ({ - options, - placeholder = "Select an option", - onChange, - className = "", - defaultValue = "", -}) => { - // Manage the selected value - const [selectedValue, setSelectedValue] = useState(defaultValue); - - const handleChange = (e: React.ChangeEvent) => { - const value = e.target.value; - setSelectedValue(value); - onChange(value); // Trigger parent handler - }; - - return ( - - ); -}; - -export default Select; diff --git a/src/components/form/date-picker.tsx b/src/components/form/date-picker.tsx deleted file mode 100644 index 9cb9f17..0000000 --- a/src/components/form/date-picker.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import { useEffect } from 'react'; -import flatpickr from 'flatpickr'; -import 'flatpickr/dist/flatpickr.css'; -import Label from './Label'; -import { CalenderIcon } from '../../icons'; -import Hook = flatpickr.Options.Hook; -import DateOption = flatpickr.Options.DateOption; - -type PropsType = { - id: string; - mode?: "single" | "multiple" | "range" | "time"; - onChange?: Hook | Hook[]; - defaultDate?: DateOption; - label?: string; - placeholder?: string; -}; - -export default function DatePicker({ - id, - mode, - onChange, - label, - defaultDate, - placeholder, -}: PropsType) { - useEffect(() => { - const flatPickr = flatpickr(`#${id}`, { - mode: mode || "single", - static: true, - monthSelectorType: "static", - dateFormat: "Y-m-d", - defaultDate, - onChange, - }); - - return () => { - if (!Array.isArray(flatPickr)) { - flatPickr.destroy(); - } - }; - }, [mode, onChange, id, defaultDate]); - - return ( -
- {label && } - -
- - - - - -
-
- ); -} diff --git a/src/components/form/form-elements/CheckboxComponents.tsx b/src/components/form/form-elements/CheckboxComponents.tsx deleted file mode 100644 index 6bf83ce..0000000 --- a/src/components/form/form-elements/CheckboxComponents.tsx +++ /dev/null @@ -1,37 +0,0 @@ -"use client"; -import React, { useState } from "react"; -import ComponentCard from "../../common/ComponentCard"; -import Checkbox from "../input/Checkbox"; - -export default function CheckboxComponents() { - const [isChecked, setIsChecked] = useState(false); - const [isCheckedTwo, setIsCheckedTwo] = useState(true); - const [isCheckedDisabled, setIsCheckedDisabled] = useState(false); - return ( - -
-
- - - Default - -
-
- -
-
- -
-
-
- ); -} diff --git a/src/components/form/form-elements/DefaultInputs.tsx b/src/components/form/form-elements/DefaultInputs.tsx deleted file mode 100644 index 36cc77e..0000000 --- a/src/components/form/form-elements/DefaultInputs.tsx +++ /dev/null @@ -1,120 +0,0 @@ -"use client"; -import React, { useState } from 'react'; -import ComponentCard from '../../common/ComponentCard'; -import Label from '../Label'; -import Input from '../input/InputField'; -import Select from '../Select'; -import { ChevronDownIcon, EyeCloseIcon, EyeIcon, TimeIcon } from '../../../icons'; -import DatePicker from '@/components/form/date-picker'; - -export default function DefaultInputs() { - const [showPassword, setShowPassword] = useState(false); - const options = [ - { value: "marketing", label: "Marketing" }, - { value: "template", label: "Template" }, - { value: "development", label: "Development" }, - ]; - const handleSelectChange = (value: string) => { - console.log("Selected value:", value); - }; - return ( - -
-
- - -
-
- - -
-
- -
- - -
-
- -
- { - // Handle your logic - console.log({ dates, currentDateString }); - }} - /> -
- -
- -
- console.log(e.target.value)} - /> - - - -
-
-
- -
- - - - - - - - -
-
-
-
- ); -} diff --git a/src/components/form/form-elements/DropZone.tsx b/src/components/form/form-elements/DropZone.tsx deleted file mode 100644 index 2fd8bb2..0000000 --- a/src/components/form/form-elements/DropZone.tsx +++ /dev/null @@ -1,77 +0,0 @@ -"use client"; -import React from "react"; -import ComponentCard from "../../common/ComponentCard"; -import { useDropzone } from "react-dropzone"; - -const DropzoneComponent: React.FC = () => { - const onDrop = (acceptedFiles: File[]) => { - console.log("Files dropped:", acceptedFiles); - // Handle file uploads here - }; - - const { getRootProps, getInputProps, isDragActive } = useDropzone({ - onDrop, - accept: { - "image/png": [], - "image/jpeg": [], - "image/webp": [], - "image/svg+xml": [], - }, - }); - return ( - -
-
- {/* Hidden Input */} - - -
- {/* Icon Container */} -
-
- - - -
-
- - {/* Text Content */} -

- {isDragActive ? "Drop Files Here" : "Drag & Drop Files Here"} -

- - - Drag and drop your PNG, JPG, WebP, SVG images here or browse - - - - Browse File - -
-
-
-
- ); -}; - -export default DropzoneComponent; diff --git a/src/components/form/form-elements/FileInputExample.tsx b/src/components/form/form-elements/FileInputExample.tsx deleted file mode 100644 index 2c96dc7..0000000 --- a/src/components/form/form-elements/FileInputExample.tsx +++ /dev/null @@ -1,23 +0,0 @@ -"use client"; -import React from "react"; -import ComponentCard from "../../common/ComponentCard"; -import FileInput from "../input/FileInput"; -import Label from "../Label"; - -export default function FileInputExample() { - const handleFileChange = (event: React.ChangeEvent) => { - const file = event.target.files?.[0]; - if (file) { - console.log("Selected file:", file.name); - } - }; - - return ( - -
- - -
-
- ); -} diff --git a/src/components/form/form-elements/InputGroup.tsx b/src/components/form/form-elements/InputGroup.tsx deleted file mode 100644 index cefd061..0000000 --- a/src/components/form/form-elements/InputGroup.tsx +++ /dev/null @@ -1,56 +0,0 @@ -"use client"; -import React from "react"; -import ComponentCard from "../../common/ComponentCard"; -import Label from "../Label"; -import Input from "../input/InputField"; -import { EnvelopeIcon } from "../../../icons"; -import PhoneInput from "../group-input/PhoneInput"; - -export default function InputGroup() { - const countries = [ - { code: "US", label: "+1" }, - { code: "GB", label: "+44" }, - { code: "CA", label: "+1" }, - { code: "AU", label: "+61" }, - ]; - const handlePhoneNumberChange = (phoneNumber: string) => { - console.log("Updated phone number:", phoneNumber); - }; - return ( - -
-
- -
- - - - -
-
-
- - -
{" "} -
- - -
-
-
- ); -} diff --git a/src/components/form/form-elements/InputStates.tsx b/src/components/form/form-elements/InputStates.tsx deleted file mode 100644 index 3ef08b5..0000000 --- a/src/components/form/form-elements/InputStates.tsx +++ /dev/null @@ -1,70 +0,0 @@ -"use client"; -import React, { useState } from "react"; -import ComponentCard from "../../common/ComponentCard"; -import Input from "../input/InputField"; -import Label from "../Label"; - -export default function InputStates() { - const [email, setEmail] = useState(""); - const [error, setError] = useState(false); - - // Simulate a validation check - const validateEmail = (value: string) => { - const isValidEmail = - /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(value); - setError(!isValidEmail); - return isValidEmail; - }; - - const handleEmailChange = (e: React.ChangeEvent) => { - const value = e.target.value; - setEmail(value); - validateEmail(value); - }; - return ( - -
- {/* Error Input */} -
- - -
- - {/* Success Input */} -
- - -
- - {/* Disabled Input */} -
- - -
-
-
- ); -} diff --git a/src/components/form/form-elements/RadioButtons.tsx b/src/components/form/form-elements/RadioButtons.tsx deleted file mode 100644 index d7ec327..0000000 --- a/src/components/form/form-elements/RadioButtons.tsx +++ /dev/null @@ -1,43 +0,0 @@ -"use client"; -import React, { useState } from "react"; -import ComponentCard from "../../common/ComponentCard"; -import Radio from "../input/Radio"; - -export default function RadioButtons() { - const [selectedValue, setSelectedValue] = useState("option2"); - - const handleRadioChange = (value: string) => { - setSelectedValue(value); - }; - return ( - -
- - - -
-
- ); -} diff --git a/src/components/form/form-elements/SelectInputs.tsx b/src/components/form/form-elements/SelectInputs.tsx deleted file mode 100644 index e19a863..0000000 --- a/src/components/form/form-elements/SelectInputs.tsx +++ /dev/null @@ -1,61 +0,0 @@ -"use client"; -import React, { useState } from "react"; -import ComponentCard from "../../common/ComponentCard"; -import Label from "../Label"; -import Select from "../Select"; -import MultiSelect from "../MultiSelect"; -import { ChevronDownIcon } from "@/icons"; - -export default function SelectInputs() { - const options = [ - { value: "marketing", label: "Marketing" }, - { value: "template", label: "Template" }, - { value: "development", label: "Development" }, - ]; - - const [selectedValues, setSelectedValues] = useState([]); - - const handleSelectChange = (value: string) => { - console.log("Selected value:", value); - }; - - const multiOptions = [ - { value: "1", text: "Option 1", selected: false }, - { value: "2", text: "Option 2", selected: false }, - { value: "3", text: "Option 3", selected: false }, - { value: "4", text: "Option 4", selected: false }, - { value: "5", text: "Option 5", selected: false }, - ]; - - return ( - -
-
- -
-