diff --git a/src/modules/dashboard/components/DashboardHeader.tsx b/src/modules/dashboard/components/DashboardHeader.tsx deleted file mode 100644 index 2c4e546..0000000 --- a/src/modules/dashboard/components/DashboardHeader.tsx +++ /dev/null @@ -1,19 +0,0 @@ -type DashboardHeaderProps = { - title?: string; - description?: string; -}; - -export default function DashboardHeader({ - title = "Dashboard", - description = "Overview of the operation", -}: DashboardHeaderProps) { - return ( -
-
-

{title}

- -

{description}

-
-
- ); -} diff --git a/src/modules/dashboard/components/RecentOrders/RecentOrder.types.ts b/src/modules/dashboard/components/RecentOrders/RecentOrder.types.ts new file mode 100644 index 0000000..393da36 --- /dev/null +++ b/src/modules/dashboard/components/RecentOrders/RecentOrder.types.ts @@ -0,0 +1,13 @@ +export type OrderStatus = "delivered" | "production" | "payment" | "review"; + +export interface Order { + id: string; + title: string; + client: string; + status: OrderStatus; +} + +export interface RecentOrdersProps { + loading?: boolean; + orders: Order[]; +} diff --git a/src/modules/dashboard/components/RecentOrders.tsx b/src/modules/dashboard/components/RecentOrders/RecentOrders.tsx similarity index 64% rename from src/modules/dashboard/components/RecentOrders.tsx rename to src/modules/dashboard/components/RecentOrders/RecentOrders.tsx index 2784a43..f1db14d 100644 --- a/src/modules/dashboard/components/RecentOrders.tsx +++ b/src/modules/dashboard/components/RecentOrders/RecentOrders.tsx @@ -1,31 +1,13 @@ -type OrderStatus = "Delivered" | "Production" | "Payment" | "Review"; +import type { RecentOrdersProps } from "./RecentOrder.types"; -type Order = { - id: string; - title: string; - client: string; - status: OrderStatus; +const statusStyles = { + delivered: "bg-emerald-500/15 text-emerald-600", + production: "bg-blue-500/15 text-blue-600", + payment: "bg-amber-500/15 text-amber-600", + review: "bg-purple-500/15 text-purple-600", }; -type RecentOrdersProps = { - loading?: boolean; -}; - -const orders: Order[] = [ - { id: "1", title: "TCC - Administração", client: "Ana Silva", status: "Delivered" }, - { id: "2", title: "Artigo Científico", client: "Carlos Souza", status: "Production" }, - { id: "3", title: "Monografia - Direito", client: "Marina Costa", status: "Payment" }, - { id: "4", title: "Revisão de Texto", client: "João Pereira", status: "Review" }, -]; - -const statusStyles: Record = { - Delivered: "bg-emerald-500/15 text-emerald-600", - Production: "bg-blue-500/15 text-blue-600", - Payment: "bg-amber-500/15 text-amber-600", - Review: "bg-purple-500/15 text-purple-600", -}; - -export default function RecentOrders({ loading = false }: RecentOrdersProps) { +export function RecentOrders({ loading = false, orders }: RecentOrdersProps) { return (
@@ -37,7 +19,7 @@ export default function RecentOrders({ loading = false }: RecentOrdersProps) { ) : ( <>

Recent Orders

- latest orders + Latest orders )}
@@ -66,7 +48,7 @@ export default function RecentOrders({ loading = false }: RecentOrdersProps) {
- + {order.status} diff --git a/src/modules/dashboard/components/RecentOrders/index.ts b/src/modules/dashboard/components/RecentOrders/index.ts new file mode 100644 index 0000000..0b31026 --- /dev/null +++ b/src/modules/dashboard/components/RecentOrders/index.ts @@ -0,0 +1 @@ +export { RecentOrders } from "./RecentOrders"; diff --git a/src/modules/dashboard/skeleton/StatsSkeleton.tsx b/src/modules/dashboard/components/Skeleton/StatsSkeleton.tsx similarity index 91% rename from src/modules/dashboard/skeleton/StatsSkeleton.tsx rename to src/modules/dashboard/components/Skeleton/StatsSkeleton.tsx index 9c737d3..84e3b78 100644 --- a/src/modules/dashboard/skeleton/StatsSkeleton.tsx +++ b/src/modules/dashboard/components/Skeleton/StatsSkeleton.tsx @@ -1,4 +1,4 @@ -export default function StatsSkeleton() { +export function StatsSkeleton() { return (
diff --git a/src/modules/dashboard/components/Skeleton/index.ts b/src/modules/dashboard/components/Skeleton/index.ts new file mode 100644 index 0000000..e14e4d1 --- /dev/null +++ b/src/modules/dashboard/components/Skeleton/index.ts @@ -0,0 +1 @@ +export { StatsSkeleton } from "./StatsSkeleton"; diff --git a/src/modules/dashboard/pages/DashboardPage.tsx b/src/modules/dashboard/pages/DashboardPage.tsx index a4d77af..e041bcf 100644 --- a/src/modules/dashboard/pages/DashboardPage.tsx +++ b/src/modules/dashboard/pages/DashboardPage.tsx @@ -1,20 +1,39 @@ +import type { Order } from "../components/RecentOrders/RecentOrder.types"; import { Helmet } from "react-helmet-async"; import { FileText, Clock, CheckCircle, DollarSign } from "lucide-react"; - -import { SidebarMenu } from "@/shared/components/Sidebar/SidebarMenu/SidebarMenu"; +import { SidebarMenu } from "@/shared/components/Sidebar"; import { getPageTitle } from "@/shared/utils"; - -import DashboardHeader from "../components/DashboardHeader"; import { Card } from "@/shared/components/Card"; -import StatsSkeleton from "../skeleton/StatsSkeleton"; -import OrdersChart from "../components/OrdersChart"; -import RecentOrders from "../components/RecentOrders"; - +import { StatsSkeleton } from "../components/Skeleton"; +import { Chart } from "@/shared/components/Chart"; +import { RecentOrders } from "../components/RecentOrders"; import { useDashboardData } from "../hooks/useDashboardData"; export function DashboardPage() { const { stats, loading } = useDashboardData(); + const recentOrders: Order[] = [ + { id: "1", title: "TCC - Administração", client: "Ana Silva", status: "delivered" }, + { id: "2", title: "Artigo Científico", client: "Carlos Souza", status: "production" }, + { id: "3", title: "Monografia - Direito", client: "Marina Costa", status: "payment" }, + { id: "4", title: "Revisão de Texto", client: "João Pereira", status: "review" }, + ]; + + const chartData = [ + { xAxis: "Jan", yAxis: 12 }, + { xAxis: "Feb", yAxis: 15 }, + { xAxis: "Mar", yAxis: 18 }, + { xAxis: "Apr", yAxis: 22 }, + { xAxis: "May", yAxis: 28 }, + { xAxis: "Jun", yAxis: 25 }, + { xAxis: "Jul", yAxis: 30 }, + { xAxis: "Aug", yAxis: 34 }, + { xAxis: "Sep", yAxis: 29 }, + { xAxis: "Oct", yAxis: 36 }, + { xAxis: "Nov", yAxis: 41 }, + { xAxis: "Dec", yAxis: 48 }, + ]; + const statsCards = stats ? [ { @@ -50,11 +69,15 @@ export function DashboardPage() { -
-
- +
+
+
+

Dashboard

+ +

Overview of the operation

+
-
+
{loading ? Array.from({ length: 4 }).map((_, index) => ) : statsCards.map((card) => ( @@ -71,13 +94,13 @@ export function DashboardPage() {
{loading ? ( -
+
) : ( - + )}
- +
diff --git a/src/modules/dashboard/skeleton/RecentOrdersSkeleton.tsx b/src/modules/dashboard/skeleton/RecentOrdersSkeleton.tsx deleted file mode 100644 index ac9c140..0000000 --- a/src/modules/dashboard/skeleton/RecentOrdersSkeleton.tsx +++ /dev/null @@ -1,23 +0,0 @@ -export default function RecentOrdersSkeleton() { - return ( -
-
-
-
-
- -
- {Array.from({ length: 4 }).map((_, index) => ( -
-
-
-
-
- -
-
- ))} -
-
- ); -} diff --git a/src/shared/components/Button/Button.styles.ts b/src/shared/components/Button/Button.styles.ts index 758d62e..5c8a486 100644 --- a/src/shared/components/Button/Button.styles.ts +++ b/src/shared/components/Button/Button.styles.ts @@ -6,9 +6,9 @@ const defaultClasses = clsx( ); const variantClasses = { - primary: "bg-primary text-primary-foreground hover:bg-primary/80", - secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/70", - danger: "bg-destructive text-destructive-foreground hover:bg-destructive/80", + primary: "bg-primary text-primary-foreground hover:bg-primary-hover", + secondary: "bg-secondary text-secondary-foreground hover:bg-secondary-hover", + danger: "bg-destructive text-destructive-foreground hover:bg-destructive-hover", }; const disabledClasses = "cursor-not-allowed opacity-50"; diff --git a/src/shared/components/Card/Card.styles.ts b/src/shared/components/Card/Card.styles.ts index 18a3040..17d4537 100644 --- a/src/shared/components/Card/Card.styles.ts +++ b/src/shared/components/Card/Card.styles.ts @@ -25,5 +25,5 @@ export const iconStyles = { ghost: "bg-transparent text-muted-foreground", }; -export const growthPositive = "bg-emerald-500/10 text-emerald-500"; -export const growthNegative = "bg-red-500/10 text-red-500"; +export const growthPositive = "bg-status-green text-status-green-text"; +export const growthNegative = "bg-status-red text-status-red-text"; diff --git a/src/modules/dashboard/components/OrdersChart.tsx b/src/shared/components/Chart/Chart.tsx similarity index 68% rename from src/modules/dashboard/components/OrdersChart.tsx rename to src/shared/components/Chart/Chart.tsx index c96bcfc..de2cd24 100644 --- a/src/modules/dashboard/components/OrdersChart.tsx +++ b/src/shared/components/Chart/Chart.tsx @@ -1,29 +1,13 @@ +import type { ChartProps } from "./Chart.types"; import { useEffect, useRef } from "react"; import * as echarts from "echarts"; -type ChartData = { - month: string; - orders: number; -}; - -const data: ChartData[] = [ - { month: "Jan", orders: 12 }, - { month: "Feb", orders: 15 }, - { month: "Mar", orders: 18 }, - { month: "Apr", orders: 22 }, - { month: "May", orders: 28 }, - { month: "Jun", orders: 25 }, - { month: "Jul", orders: 30 }, - { month: "Aug", orders: 34 }, - { month: "Sep", orders: 29 }, - { month: "Oct", orders: 36 }, - { month: "Nov", orders: 41 }, - { month: "Dec", orders: 48 }, -]; - -export default function OrdersChart() { +export function Chart({ title, description, data }: ChartProps) { const chartRef = useRef(null); const chartInstance = useRef(null); + const theme = localStorage.getItem("theme"); + const chartLineColor = + theme === "dark" || (!theme && window.matchMedia("(prefers-color-scheme: dark)").matches) ? "#334155" : "#cbd5e1"; useEffect(() => { if (!chartRef.current) return; @@ -43,14 +27,14 @@ export default function OrdersChart() { xAxis: { type: "category", - data: data.map((d) => d.month), + data: data.map((d) => d.xAxis), axisLine: { show: false }, axisTick: { show: false }, splitLine: { show: true, lineStyle: { type: "dashed", - color: "#e5e7eb", + color: chartLineColor, }, }, }, @@ -63,14 +47,14 @@ export default function OrdersChart() { show: true, lineStyle: { type: "dashed", - color: "#e5e7eb", + color: chartLineColor, }, }, }, series: [ { - data: data.map((d) => d.orders), + data: data.map((d) => d.yAxis), type: "line", smooth: true, @@ -108,13 +92,13 @@ export default function OrdersChart() { resizeObserver.disconnect(); chartInstance.current?.dispose(); }; - }, []); + }, [chartLineColor, data]); return ( -
+
-

Orders per Month

- last 12 months +

{title}

+ {description}
diff --git a/src/shared/components/Chart/Chart.types.ts b/src/shared/components/Chart/Chart.types.ts new file mode 100644 index 0000000..594eb2e --- /dev/null +++ b/src/shared/components/Chart/Chart.types.ts @@ -0,0 +1,10 @@ +export type ChartData = { + xAxis: string; + yAxis: number; +}; + +export interface ChartProps { + title?: string; + description?: string; + data: ChartData[]; +} diff --git a/src/shared/components/Chart/index.ts b/src/shared/components/Chart/index.ts new file mode 100644 index 0000000..a5a8f85 --- /dev/null +++ b/src/shared/components/Chart/index.ts @@ -0,0 +1 @@ +export { Chart } from "./Chart"; diff --git a/src/shared/components/InputField/InputField.styles.ts b/src/shared/components/InputField/InputField.styles.ts index 93caf27..bcb8a2d 100644 --- a/src/shared/components/InputField/InputField.styles.ts +++ b/src/shared/components/InputField/InputField.styles.ts @@ -1,13 +1,13 @@ import clsx from "clsx"; const defaultClasses = clsx( - "w-full appearance-none rounded border py-2 leading-tight shadow", - "transition-all focus:outline-none" + "w-full appearance-none rounded border py-2 leading-tight shadow-xs shadow-border", + "transition-all focus:outline-none bg-card" ); const stateClasses = { default: clsx( - "border-input text-foreground placeholder:text-foreground/30", + "border-input text-foreground placeholder:text-placeholder", "focus:border-primary focus:ring focus:ring-ring" ), error: clsx( @@ -18,9 +18,12 @@ const stateClasses = { const disabledClasses = "cursor-not-allowed opacity-50"; +const bgClass = "bg-card"; + export function getInputFieldClasses( hasError: boolean, disabled: boolean, + bgTransparent: boolean, hasLeftAddon: boolean, hasRightAddon: boolean ): string { @@ -30,6 +33,7 @@ export function getInputFieldClasses( hasError && stateClasses["error"], hasLeftAddon ? "pl-10" : "pl-3", hasRightAddon ? "pr-10" : "pr-3", - disabled && disabledClasses + disabled && disabledClasses, + bgTransparent && bgClass ); } diff --git a/src/shared/components/InputField/InputField.tsx b/src/shared/components/InputField/InputField.tsx index 0fafa39..41df9c4 100644 --- a/src/shared/components/InputField/InputField.tsx +++ b/src/shared/components/InputField/InputField.tsx @@ -4,7 +4,18 @@ import { getInputFieldClasses } from "./InputField.styles"; export const InputField = forwardRef( ( - { label, showLabel = true, helperText, errorMessage, leftAddon, rightAddon, id: idProp, disabled = false, ...rest }, + { + label, + showLabel = true, + helperText, + errorMessage, + leftAddon, + rightAddon, + id: idProp, + disabled = false, + bgTransparent = false, + ...rest + }, ref ) => { const generatedId = useId(); @@ -13,12 +24,15 @@ export const InputField = forwardRef( return (
-