Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 0 additions & 19 deletions src/modules/dashboard/components/DashboardHeader.tsx

This file was deleted.

13 changes: 13 additions & 0 deletions src/modules/dashboard/components/RecentOrders/RecentOrder.types.ts
Original file line number Diff line number Diff line change
@@ -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[];
}
Original file line number Diff line number Diff line change
@@ -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<OrderStatus, string> = {
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 (
<div className="bg-card border-border/60 flex flex-col rounded-xl border p-4 shadow-sm md:p-6">
<div className="mb-4 flex items-center justify-between md:mb-5">
Expand All @@ -37,7 +19,7 @@ export default function RecentOrders({ loading = false }: RecentOrdersProps) {
) : (
<>
<h3 className="text-sm font-semibold md:text-base">Recent Orders</h3>
<span className="text-muted-foreground text-xs">latest orders</span>
<span className="text-muted-foreground text-xs">Latest orders</span>
</>
)}
</div>
Expand Down Expand Up @@ -66,7 +48,7 @@ export default function RecentOrders({ loading = false }: RecentOrdersProps) {
</div>
</div>

<span className={`rounded-md px-2.5 py-1 text-xs font-medium ${statusStyles[order.status]}`}>
<span className={`rounded-md px-2.5 py-1 text-xs font-medium capitalize ${statusStyles[order.status]}`}>
{order.status}
</span>
</div>
Expand Down
1 change: 1 addition & 0 deletions src/modules/dashboard/components/RecentOrders/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { RecentOrders } from "./RecentOrders";
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export default function StatsSkeleton() {
export function StatsSkeleton() {
return (
<div className="bg-card border-border/60 animate-pulse rounded-xl border p-5">
<div className="flex items-start justify-between">
Expand Down
1 change: 1 addition & 0 deletions src/modules/dashboard/components/Skeleton/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { StatsSkeleton } from "./StatsSkeleton";
53 changes: 38 additions & 15 deletions src/modules/dashboard/pages/DashboardPage.tsx
Original file line number Diff line number Diff line change
@@ -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
? [
{
Expand Down Expand Up @@ -50,11 +69,15 @@ export function DashboardPage() {
</Helmet>

<SidebarMenu>
<main className="mt-14 min-h-screen md:mt-0 md:p-6">
<div className="mx-auto w-full space-y-10 md:space-y-16">
<DashboardHeader />
<main className="min-h-screen">
<div className="mx-auto w-full">
<div className="mb-12">
<h1 className="text-2xl font-semibold tracking-tight">Dashboard</h1>

<p className="text-muted-foreground text-sm">Overview of the operation</p>
</div>

<div className="grid min-w-0 grid-cols-1 gap-6 *:min-w-0 sm:grid-cols-2 xl:grid-cols-4">
<div className="mb-6 grid min-w-0 grid-cols-1 gap-6 *:min-w-0 sm:grid-cols-2 xl:grid-cols-4">
{loading
? Array.from({ length: 4 }).map((_, index) => <StatsSkeleton key={index} />)
: statsCards.map((card) => (
Expand All @@ -71,13 +94,13 @@ export function DashboardPage() {
<section className="grid grid-cols-1 gap-6 xl:grid-cols-3">
<div className="min-w-0 xl:col-span-2">
{loading ? (
<div className="bg-card border-border/60 h-85 animate-pulse rounded-xl border" />
<div className="bg-card border-border h-85 animate-pulse rounded-xl border" />
) : (
<OrdersChart />
<Chart title={"Orders per month"} description={"Last 12 months"} data={chartData} />
)}
</div>

<RecentOrders loading={loading} />
<RecentOrders loading={loading} orders={recentOrders} />
</section>
</div>
</main>
Expand Down
23 changes: 0 additions & 23 deletions src/modules/dashboard/skeleton/RecentOrdersSkeleton.tsx

This file was deleted.

6 changes: 3 additions & 3 deletions src/shared/components/Button/Button.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
4 changes: 2 additions & 2 deletions src/shared/components/Card/Card.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Original file line number Diff line number Diff line change
@@ -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<HTMLDivElement | null>(null);
const chartInstance = useRef<echarts.ECharts | null>(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;
Expand All @@ -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,
},
},
},
Expand All @@ -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,

Expand Down Expand Up @@ -108,13 +92,13 @@ export default function OrdersChart() {
resizeObserver.disconnect();
chartInstance.current?.dispose();
};
}, []);
}, [chartLineColor, data]);

return (
<div className="bg-card border-border/60 w-full rounded-xl border p-3 shadow-sm sm:p-6">
<div className="bg-card border-border w-full rounded-xl border p-3 shadow-sm sm:p-6">
<div className="mb-3 flex items-center justify-between sm:mb-6">
<h3 className="text-sm font-semibold">Orders per Month</h3>
<span className="text-muted-foreground text-xs">last 12 months</span>
<h3 className="text-sm font-semibold">{title}</h3>
<span className="text-muted-foreground text-xs">{description}</span>
</div>

<div ref={chartRef} className="h-85 w-full min-w-0 sm:h-90" />
Expand Down
10 changes: 10 additions & 0 deletions src/shared/components/Chart/Chart.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export type ChartData = {
xAxis: string;
yAxis: number;
};

export interface ChartProps {
title?: string;
description?: string;
data: ChartData[];
}
1 change: 1 addition & 0 deletions src/shared/components/Chart/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { Chart } from "./Chart";
12 changes: 8 additions & 4 deletions src/shared/components/InputField/InputField.styles.ts
Original file line number Diff line number Diff line change
@@ -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(
Expand All @@ -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 {
Expand All @@ -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
);
}
Loading
Loading