Skip to content

Commit

Permalink
feat: ✨ add mobile responsive support
Browse files Browse the repository at this point in the history
  • Loading branch information
neopromic committed Nov 22, 2024
1 parent 5f7fe91 commit 5c7c71e
Show file tree
Hide file tree
Showing 15 changed files with 547 additions and 88 deletions.
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { Button } from "@/app/_components/ui/button";
import { CardContent, CardHeader, CardTitle } from "@/app/_components/ui/card";
import { ScrollArea } from "@/app/_components/ui/scroll-area";
import Link from "next/link";
import { Transactions } from "@prisma/client";
import TransactionCard from "./transaction-card";

interface LastTransactionsProps {
lastTransactions: Transactions[];
}

const LastTransactions = ({ lastTransactions }: LastTransactionsProps) => {
return (
<ScrollArea className="max-h-[calc(100vh)] rounded-md border">
<div className="rounded-md border">
<CardHeader className="flex-row items-center justify-between">
<CardTitle className="font-bold">Últimas transações</CardTitle>
<Link href="/transactions">
Expand All @@ -19,12 +19,12 @@ const LastTransactions = ({ lastTransactions }: LastTransactionsProps) => {
</Button>
</Link>
</CardHeader>
<CardContent className="w-full space-y-6">
<CardContent className="space-y-6">
{lastTransactions.map((transaction) => (
<TransactionCard key={transaction.id} transaction={transaction} />
))}
</CardContent>
</ScrollArea>
</div>
);
};

Expand Down
26 changes: 20 additions & 6 deletions app/(authenticated)/dashboard/_components/summar-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,37 @@ const SummaryCard = ({
size = "sm",
}: SummaryCardProps) => {
return (
<Card className={`${size === "lg" ? "bg-white bg-opacity-10" : ""}`}>
<CardHeader className="flex-row items-center gap-2">
<Card
className={cn(
size === "lg" ? "bg-white bg-opacity-10" : "",
"p-2 sm:p-4",
)}
>
<CardHeader className="flex-row items-center gap-2 p-2 sm:p-4">
<div className="rounded-lg bg-white bg-opacity-[3%] p-2">{icon}</div>
<p
className={cn(
"text-muted-foreground",
size === "sm" ? "text-muted-foreground" : "text-white opacity-70",
"text-sm sm:text-base",
)}
>
{title}
</p>
</CardHeader>
<CardContent className="flex justify-between">
<p className={`font-bold ${size === "sm" ? "text-2xl" : "text-4xl"}`}>
<CardContent className="flex flex-col justify-between space-y-2 p-2 sm:flex-row sm:space-y-0 sm:p-4">
<p
className={cn(
"font-bold",
size === "sm" ? "text-xl sm:text-2xl" : "text-2xl sm:text-4xl",
)}
>
{formatCurrency(Number(amount))}
</p>
{size === "lg" && <AddTransactionButton />}
{size === "lg" && (
<div className="">
<AddTransactionButton />
</div>
)}
</CardContent>
</Card>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const SummaryCards = async ({
icon={<WalletIcon size={16} />}
size="lg"
/>
<div className="grid grid-cols-3 gap-6">
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3">
<SummaryCard
title="Investido"
amount={investmentsTotal.toString()}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,11 @@ const TransactionsPieChart = ({
];

return (
<Card className="flex flex-col py-6">
<Card className="col-span-2 flex w-full flex-col py-6 md:col-span-2 lg:col-span-1">
<CardContent className="flex-1 pb-0">
<ChartContainer
config={chartConfig}
className="mx-auto aspect-square max-h-[250px]"
className="mx-auto aspect-square max-h-[250px] w-full"
>
<PieChart>
<ChartTooltip
Expand Down
36 changes: 20 additions & 16 deletions app/(authenticated)/dashboard/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,27 +32,31 @@ const Home = async ({ searchParams: { month = "1" } }: HomeProps) => {

return (
<div className="flex h-[calc(100vh-72px)] flex-col gap-6 p-6">
<div className="grid h-full grid-cols-[2fr,1fr] gap-6">
<ScrollArea className="h-full pr-6">
<div className="space-y-6 overflow-hidden">
<div className="flex justify-between">
<h1 className="text-2xl font-bold">Dashboard</h1>
<TimeSelect defaultValue={month} />
</div>
<ScrollArea className="h-full pb-12 lg:py-0">
<div className="grid h-full gap-6 lg:grid-cols-[2fr,1fr]">
<div className="pr-0 lg:pr-6">
<div className="space-y-6 overflow-hidden">
<div className="flex flex-col gap-4 sm:flex-row sm:justify-between sm:gap-0">
<h1 className="text-2xl font-bold">Dashboard</h1>
<TimeSelect defaultValue={month} />
</div>

<SummaryCards month={monthNumber.toString()} {...dashboard} />
<SummaryCards month={monthNumber.toString()} {...dashboard} />

<div className="grid grid-cols-3 grid-rows-1 gap-6 overflow-hidden">
<TransactionsPieChart {...dashboard} />
<ExpensesPerCategory
expensesPerCategory={dashboard.totalExpensePerCategory}
/>
<div className="grid grid-cols-1 gap-6 overflow-hidden md:grid-cols-2 lg:grid-cols-3">
<TransactionsPieChart {...dashboard} />
<ExpensesPerCategory
expensesPerCategory={dashboard.totalExpensePerCategory}
/>
</div>
</div>
</div>
</ScrollArea>

<LastTransactions lastTransactions={dashboard.lastTransactions} />
</div>
<div className="lg:h-full">
<LastTransactions lastTransactions={dashboard.lastTransactions} />
</div>
</div>
</ScrollArea>
</div>
);
};
Expand Down
8 changes: 4 additions & 4 deletions app/_components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
"use client";

import { UserButton } from "@clerk/nextjs";
import Image from "next/image";
import Link from "next/link";
import { usePathname } from "next/navigation";
import UserAvatarButton from "./user-avatar-button";

const Header = ({ isEnabled = true }: { isEnabled?: boolean }) => {
const pathname = usePathname();
Expand All @@ -28,11 +28,11 @@ const Header = ({ isEnabled = true }: { isEnabled?: boolean }) => {
return (
<header className="sticky left-0 top-0 z-50 flex h-[72px] min-h-[72px] items-center justify-between border-b bg-background px-6">
<div className="flex items-center gap-8">
<Link href="/dashboard">
<Link href={`/dashboard?month=${new Date().getMonth() + 1}`}>
<Image src="/logo.svg" alt="logo" width={173} height={32} />
</Link>

<nav className="flex items-center gap-4">
<nav className="hidden items-center gap-4 lg:flex">
{navigation.map((item) => (
<Link
key={item.href}
Expand All @@ -49,7 +49,7 @@ const Header = ({ isEnabled = true }: { isEnabled?: boolean }) => {
</nav>
</div>

<UserButton showName />
<UserAvatarButton />
</header>
);
};
Expand Down
50 changes: 50 additions & 0 deletions app/_components/ui/avatar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
"use client";

import * as React from "react";
import * as AvatarPrimitive from "@radix-ui/react-avatar";

import { cn } from "@/app/_lib/utils";

const Avatar = React.forwardRef<
React.ElementRef<typeof AvatarPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>
>(({ className, ...props }, ref) => (
<AvatarPrimitive.Root
ref={ref}
className={cn(
"relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",
className,
)}
{...props}
/>
));
Avatar.displayName = AvatarPrimitive.Root.displayName;

const AvatarImage = React.forwardRef<
React.ElementRef<typeof AvatarPrimitive.Image>,
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>
>(({ className, ...props }, ref) => (
<AvatarPrimitive.Image
ref={ref}
className={cn("aspect-square h-full w-full", className)}
{...props}
/>
));
AvatarImage.displayName = AvatarPrimitive.Image.displayName;

const AvatarFallback = React.forwardRef<
React.ElementRef<typeof AvatarPrimitive.Fallback>,
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>
>(({ className, ...props }, ref) => (
<AvatarPrimitive.Fallback
ref={ref}
className={cn(
"flex h-full w-full items-center justify-center rounded-full bg-muted",
className,
)}
{...props}
/>
));
AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;

export { Avatar, AvatarImage, AvatarFallback };
26 changes: 13 additions & 13 deletions app/_components/ui/button.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import * as React from "react"
import { Slot } from "@radix-ui/react-slot"
import { cva, type VariantProps } from "class-variance-authority"
import * as React from "react";
import { Slot } from "@radix-ui/react-slot";
import { cva, type VariantProps } from "class-variance-authority";

import { cn } from "@/app/_lib/utils";

const buttonVariants = cva(
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
"inline-flex items-center rounded-full justify-center gap-2 whitespace-nowrap text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
{
variants: {
variant: {
Expand All @@ -30,27 +30,27 @@ const buttonVariants = cva(
variant: "default",
size: "default",
},
}
)
},
);

export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean
asChild?: boolean;
}

const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : "button"
const Comp = asChild ? Slot : "button";
return (
<Comp
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
{...props}
/>
)
}
)
Button.displayName = "Button"
);
},
);
Button.displayName = "Button";

export { Button, buttonVariants }
export { Button, buttonVariants };
Loading

0 comments on commit 5c7c71e

Please sign in to comment.