feat: add new UI components including Drawer, InputOTP, Pagination, Sidebar, Sonner, and ToggleGroup
Some checks failed
GBCI / build (push) Failing after 2m18s
Some checks failed
GBCI / build (push) Failing after 2m18s
- Implemented Drawer component for modal-like functionality. - Added InputOTP component for handling one-time password inputs. - Created Pagination component for navigating through paginated content. - Developed Sidebar component with collapsible and mobile-friendly features. - Integrated Sonner for toast notifications with theme support. - Introduced ToggleGroup for grouping toggle buttons with context support. - Added useIsMobile hook to determine mobile view based on screen width.
This commit is contained in:
parent
473fae930a
commit
1d458886dd
2 changed files with 760 additions and 532 deletions
|
@ -1,33 +1,259 @@
|
||||||
import React from 'react';
|
"use client";
|
||||||
import { TeamSwitcher } from './components/TeamSwitcher';
|
import React, { useState } from 'react';
|
||||||
import { MainNav } from './components/MainNav';
|
|
||||||
import { Search } from './components/Search';
|
const Dashboard = () => {
|
||||||
import { UserNav } from './components/UserNav';
|
const [dateRange, setDateRange] = useState({
|
||||||
import { CalendarDateRangePicker } from './components/DateRangePicker';
|
startDate: new Date(),
|
||||||
import { Overview } from './components/Overview';
|
endDate: new Date()
|
||||||
import { RecentSales } from './components/RecentSales';
|
});
|
||||||
|
const [selectedTeam, setSelectedTeam] = useState({
|
||||||
|
label: "Alicia Koch",
|
||||||
|
value: "personal"
|
||||||
|
});
|
||||||
|
const [teamSwitcherOpen, setTeamSwitcherOpen] = useState(false);
|
||||||
|
const [showNewTeamDialog, setShowNewTeamDialog] = useState(false);
|
||||||
|
const [userNavOpen, setUserNavOpen] = useState(false);
|
||||||
|
|
||||||
|
const formatDate = (date) => {
|
||||||
|
return date.toLocaleDateString('en-US', {
|
||||||
|
month: 'short',
|
||||||
|
day: '2-digit',
|
||||||
|
year: 'numeric'
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const salesData = [
|
||||||
|
{ name: "Olivia Martin", email: "olivia.martin@email.com", amount: "+$1,999.00" },
|
||||||
|
{ name: "Jackson Lee", email: "jackson.lee@email.com", amount: "+$39.00" },
|
||||||
|
{ name: "Isabella Nguyen", email: "isabella.nguyen@email.com", amount: "+$299.00" },
|
||||||
|
{ name: "William Kim", email: "will@email.com", amount: "+$99.00" },
|
||||||
|
{ name: "Sofia Davis", email: "sofia.davis@email.com", amount: "+$39.00" },
|
||||||
|
];
|
||||||
|
|
||||||
|
const groups = [
|
||||||
|
{
|
||||||
|
label: "Personal Account",
|
||||||
|
teams: [
|
||||||
|
{ label: "Alicia Koch", value: "personal" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Teams",
|
||||||
|
teams: [
|
||||||
|
{ label: "Acme Inc.", value: "acme-inc" },
|
||||||
|
{ label: "Monsters Inc.", value: "monsters" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const CalendarDateRangePicker = () => (
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<button
|
||||||
|
className="px-3 py-1 border rounded text-foreground border-border hover:bg-accent hover:text-accent-foreground transition-colors"
|
||||||
|
onClick={() => {
|
||||||
|
const date = new Date(prompt("Enter start date (YYYY-MM-DD)") || dateRange.startDate);
|
||||||
|
setDateRange(prev => ({ ...prev, startDate: date }));
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Start: {formatDate(dateRange.startDate)}
|
||||||
|
</button>
|
||||||
|
<span className="text-foreground">to</span>
|
||||||
|
<button
|
||||||
|
className="px-3 py-1 border rounded text-foreground border-border hover:bg-accent hover:text-accent-foreground transition-colors"
|
||||||
|
onClick={() => {
|
||||||
|
const date = new Date(prompt("Enter end date (YYYY-MM-DD)") || dateRange.endDate);
|
||||||
|
setDateRange(prev => ({ ...prev, endDate: date }));
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
End: {formatDate(dateRange.endDate)}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
const MainNav = () => (
|
||||||
|
<nav className="flex space-x-4">
|
||||||
|
{['Overview', 'Customers', 'Products', 'Settings'].map((item) => (
|
||||||
|
<button
|
||||||
|
key={item}
|
||||||
|
className="px-3 py-2 text-sm font-medium text-foreground hover:text-primary transition-colors"
|
||||||
|
>
|
||||||
|
{item}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</nav>
|
||||||
|
);
|
||||||
|
|
||||||
|
const Search = () => (
|
||||||
|
<div className="relative max-w-md">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="Search..."
|
||||||
|
className="w-full pl-8 pr-4 py-2 rounded-full border focus:outline-none focus:ring-2 bg-input border-border focus:ring-ring text-foreground placeholder:text-muted-foreground"
|
||||||
|
/>
|
||||||
|
<svg
|
||||||
|
className="absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke="currentColor"
|
||||||
|
>
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
const TeamSwitcher = () => (
|
||||||
|
<div className="relative">
|
||||||
|
<button
|
||||||
|
onClick={() => setTeamSwitcherOpen(true)}
|
||||||
|
className="flex items-center space-x-2 hover:bg-accent hover:text-accent-foreground p-2 rounded transition-colors"
|
||||||
|
>
|
||||||
|
<div className="w-8 h-8 rounded-full bg-secondary flex items-center justify-center text-secondary-foreground">
|
||||||
|
{selectedTeam.label[0]}
|
||||||
|
</div>
|
||||||
|
<span className="text-foreground">{selectedTeam.label}</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{teamSwitcherOpen && (
|
||||||
|
<div className="absolute z-10 mt-2 w-56 bg-popover rounded-md shadow-lg border border-border">
|
||||||
|
<div className="p-2">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="Search team..."
|
||||||
|
className="w-full p-2 border rounded bg-input border-border text-foreground placeholder:text-muted-foreground"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{groups.map((group) => (
|
||||||
|
<div key={group.label} className="py-1">
|
||||||
|
<p className="px-3 py-1 text-sm font-medium text-muted-foreground">{group.label}</p>
|
||||||
|
{group.teams.map((team) => (
|
||||||
|
<button
|
||||||
|
key={team.value}
|
||||||
|
onClick={() => {
|
||||||
|
setSelectedTeam(team);
|
||||||
|
setTeamSwitcherOpen(false);
|
||||||
|
}}
|
||||||
|
className="w-full text-left px-3 py-2 hover:bg-accent hover:text-accent-foreground text-popover-foreground transition-colors"
|
||||||
|
>
|
||||||
|
{team.label}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
<div className="border-t border-border p-2">
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
setTeamSwitcherOpen(false);
|
||||||
|
setShowNewTeamDialog(true);
|
||||||
|
}}
|
||||||
|
className="w-full p-2 text-left hover:bg-accent hover:text-accent-foreground text-popover-foreground transition-colors"
|
||||||
|
>
|
||||||
|
Create Team
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{showNewTeamDialog && (
|
||||||
|
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center">
|
||||||
|
<div className="bg-popover p-4 rounded-md border border-border">
|
||||||
|
<h3 className="text-lg font-medium mb-4 text-popover-foreground">Create team</h3>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="Team name"
|
||||||
|
className="w-full p-2 border rounded mb-4 bg-input border-border text-foreground placeholder:text-muted-foreground"
|
||||||
|
/>
|
||||||
|
<div className="flex justify-end space-x-2">
|
||||||
|
<button
|
||||||
|
onClick={() => setShowNewTeamDialog(false)}
|
||||||
|
className="px-4 py-2 border rounded border-border text-foreground hover:bg-accent hover:text-accent-foreground transition-colors"
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => setShowNewTeamDialog(false)}
|
||||||
|
className="px-4 py-2 bg-primary text-primary-foreground rounded hover:opacity-90 transition-opacity"
|
||||||
|
>
|
||||||
|
Create
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
const UserNav = () => (
|
||||||
|
<div className="relative">
|
||||||
|
<button
|
||||||
|
onClick={() => setUserNavOpen(!userNavOpen)}
|
||||||
|
className="w-8 h-8 rounded-full bg-secondary flex items-center justify-center text-secondary-foreground hover:bg-accent hover:text-accent-foreground transition-colors"
|
||||||
|
>
|
||||||
|
U
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{userNavOpen && (
|
||||||
|
<div className="absolute right-0 mt-2 w-48 bg-popover rounded-md shadow-lg z-10 border border-border">
|
||||||
|
<div className="p-2 border-b border-border">
|
||||||
|
<p className="font-medium text-popover-foreground">shadcn</p>
|
||||||
|
<p className="text-sm text-muted-foreground">m@example.com</p>
|
||||||
|
</div>
|
||||||
|
{['Profile', 'Billing', 'Settings', 'New Team', 'Log out'].map((item) => (
|
||||||
|
<button
|
||||||
|
key={item}
|
||||||
|
className="w-full text-left px-3 py-2 hover:bg-accent hover:text-accent-foreground text-popover-foreground transition-colors"
|
||||||
|
>
|
||||||
|
{item}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
const Overview = () => (
|
||||||
|
<div className="p-4 border rounded-lg border-border">
|
||||||
|
<div className="flex justify-between items-end h-40">
|
||||||
|
{[100, 80, 60, 40, 20].map((height, index) => (
|
||||||
|
<div
|
||||||
|
key={index}
|
||||||
|
className="w-8 opacity-60"
|
||||||
|
style={{
|
||||||
|
height: `${height}px`,
|
||||||
|
backgroundColor: `hsl(var(--chart-${(index % 5) + 1}))`
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
const RecentSales = () => (
|
||||||
|
<div className="space-y-4">
|
||||||
|
{salesData.map((item, index) => (
|
||||||
|
<div key={index} className="flex items-center justify-between p-2 border-b border-border">
|
||||||
|
<div className="flex items-center space-x-3">
|
||||||
|
<div className="w-8 h-8 rounded-full bg-secondary flex items-center justify-center text-secondary-foreground">
|
||||||
|
{item.name[0]}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p className="font-medium text-foreground">{item.name}</p>
|
||||||
|
<p className="text-sm text-muted-foreground">{item.email}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span className="font-medium text-foreground">{item.amount}</span>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
export default function DashboardScreen() {
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-gray-50">
|
<div className="min-h-screen bg-background text-foreground">
|
||||||
<header className="bg-white border-b">
|
|
||||||
<div className="container flex items-center justify-between h-16 px-4">
|
|
||||||
<TeamSwitcher />
|
|
||||||
<MainNav />
|
|
||||||
<div className="flex items-center space-x-4">
|
|
||||||
<Search />
|
|
||||||
<UserNav />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<main className="container p-4 space-y-4">
|
<main className="container p-4 space-y-4">
|
||||||
s
|
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<h1 className="text-2xl font-bold">Dashboard</h1>
|
<h1 className="text-2xl font-bold text-foreground">Dashboard</h1>
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2">
|
||||||
<CalendarDateRangePicker />
|
<CalendarDateRangePicker />
|
||||||
<button className="px-4 py-2 bg-blue-500 text-white rounded">
|
<button className="px-4 py-2 bg-primary text-primary-foreground rounded hover:opacity-90 transition-opacity">
|
||||||
Download
|
Download
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -40,26 +266,28 @@ s
|
||||||
{ title: "Sales", value: "+12,234", subtext: "+19% from last month" },
|
{ title: "Sales", value: "+12,234", subtext: "+19% from last month" },
|
||||||
{ title: "Active Now", value: "+573", subtext: "+201 since last hour" },
|
{ title: "Active Now", value: "+573", subtext: "+201 since last hour" },
|
||||||
].map((card, index) => (
|
].map((card, index) => (
|
||||||
<div key={index} className="p-6 bg-white border rounded-lg">
|
<div key={index} className="p-6 bg-card border rounded-lg border-border">
|
||||||
<h3 className="text-sm font-medium text-gray-500">{card.title}</h3>
|
<h3 className="text-sm font-medium text-muted-foreground">{card.title}</h3>
|
||||||
<p className="text-2xl font-bold mt-1">{card.value}</p>
|
<p className="text-2xl font-bold mt-1 text-card-foreground">{card.value}</p>
|
||||||
<p className="text-xs text-gray-500 mt-1">{card.subtext}</p>
|
<p className="text-xs text-muted-foreground mt-1">{card.subtext}</p>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid gap-4 md:grid-cols-2">
|
<div className="grid gap-4 md:grid-cols-2">
|
||||||
<div className="p-6 bg-white border rounded-lg">
|
<div className="p-6 bg-card border rounded-lg border-border">
|
||||||
<h3 className="text-lg font-medium mb-4">Overview</h3>
|
<h3 className="text-lg font-medium mb-4 text-card-foreground">Overview</h3>
|
||||||
<Overview />
|
<Overview />
|
||||||
</div>
|
</div>
|
||||||
<div className="p-6 bg-white border rounded-lg space-y-4">
|
<div className="p-6 bg-card border rounded-lg space-y-4 border-border">
|
||||||
<h3 className="text-lg font-medium">Recent Sales</h3>
|
<h3 className="text-lg font-medium text-card-foreground">Recent Sales</h3>
|
||||||
<p>You made 265 sales this month.</p>
|
<p className="text-card-foreground">You made 265 sales this month.</p>
|
||||||
<RecentSales />
|
<RecentSales />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
export default Dashboard;
|
|
@ -1,64 +1,64 @@
|
||||||
"use client"
|
"use client"
|
||||||
import { accounts, mails } from "./data"
|
import { accounts, mails } from "./data"
|
||||||
|
|
||||||
import * as React from "react"
|
import * as React from "react"
|
||||||
import {
|
import {
|
||||||
AlertCircle, Archive, ArchiveX, Clock, File, Forward, Inbox, Mail as MailIcon,
|
AlertCircle, Archive, ArchiveX, Clock, File, Forward, Inbox, Mail as MailIcon,
|
||||||
MessagesSquare, MoreVertical, Reply, ReplyAll, Search, Send, ShoppingCart,
|
MessagesSquare, MoreVertical, Reply, ReplyAll, Search, Send, ShoppingCart,
|
||||||
Trash2, Users2, LucideIcon
|
Trash2, Users2, LucideIcon
|
||||||
} from "lucide-react"
|
} from "lucide-react"
|
||||||
import { useMail } from "./use-mail"
|
import { useMail } from "./use-mail"
|
||||||
import { cn } from "@/lib/utils"
|
import { cn } from "@/lib/utils"
|
||||||
import { format, formatDistanceToNow, addDays, addHours, nextSaturday } from "date-fns"
|
import { format, formatDistanceToNow, addDays, addHours, nextSaturday } from "date-fns"
|
||||||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
|
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
|
||||||
import { Badge } from "@/components/ui/badge"
|
import { Badge } from "@/components/ui/badge"
|
||||||
import { Button } from "@/components/ui/button"
|
import { Button } from "@/components/ui/button"
|
||||||
import { Calendar } from "@/components/ui/calendar"
|
import { Calendar } from "@/components/ui/calendar"
|
||||||
import {
|
import {
|
||||||
DropdownMenu,
|
DropdownMenu,
|
||||||
DropdownMenuContent,
|
DropdownMenuContent,
|
||||||
DropdownMenuItem,
|
DropdownMenuItem,
|
||||||
DropdownMenuTrigger,
|
DropdownMenuTrigger,
|
||||||
} from "@/components/ui/dropdown-menu"
|
} from "@/components/ui/dropdown-menu"
|
||||||
import { Input } from "@/components/ui/input"
|
import { Input } from "@/components/ui/input"
|
||||||
import { Label } from "@/components/ui/label"
|
import { Label } from "@/components/ui/label"
|
||||||
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"
|
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"
|
||||||
import {
|
import {
|
||||||
ResizableHandle,
|
ResizableHandle,
|
||||||
ResizablePanel,
|
ResizablePanel,
|
||||||
ResizablePanelGroup,
|
ResizablePanelGroup,
|
||||||
} from "@/components/ui/resizable"
|
} from "@/components/ui/resizable"
|
||||||
import { ScrollArea } from "@/components/ui/scroll-area"
|
import { ScrollArea } from "@/components/ui/scroll-area"
|
||||||
import {
|
import {
|
||||||
Select,
|
Select,
|
||||||
SelectContent,
|
SelectContent,
|
||||||
SelectItem,
|
SelectItem,
|
||||||
SelectTrigger,
|
SelectTrigger,
|
||||||
SelectValue,
|
SelectValue,
|
||||||
} from "@/components/ui/select"
|
} from "@/components/ui/select"
|
||||||
import { Separator } from "@/components/ui/separator"
|
import { Separator } from "@/components/ui/separator"
|
||||||
import { Switch } from "@/components/ui/switch"
|
import { Switch } from "@/components/ui/switch"
|
||||||
import {
|
import {
|
||||||
Tabs,
|
Tabs,
|
||||||
TabsContent,
|
TabsContent,
|
||||||
TabsList,
|
TabsList,
|
||||||
TabsTrigger,
|
TabsTrigger,
|
||||||
} from "@/components/ui/tabs"
|
} from "@/components/ui/tabs"
|
||||||
import { Textarea } from "@/components/ui/textarea"
|
import { Textarea } from "@/components/ui/textarea"
|
||||||
import {
|
import {
|
||||||
Tooltip,
|
Tooltip,
|
||||||
TooltipContent,
|
TooltipContent,
|
||||||
TooltipTrigger,
|
TooltipTrigger,
|
||||||
TooltipProvider,
|
TooltipProvider,
|
||||||
} from "@/components/ui/tooltip"
|
} from "@/components/ui/tooltip"
|
||||||
|
|
||||||
interface Account {
|
interface Account {
|
||||||
label: string
|
label: string
|
||||||
email: string
|
email: string
|
||||||
icon: React.ReactNode
|
icon: React.ReactNode
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Mail {
|
interface Mail {
|
||||||
id: string
|
id: string
|
||||||
name: string
|
name: string
|
||||||
email: string
|
email: string
|
||||||
|
@ -67,31 +67,31 @@ interface Mail {
|
||||||
date: string
|
date: string
|
||||||
read: boolean
|
read: boolean
|
||||||
labels: string[]
|
labels: string[]
|
||||||
}
|
}
|
||||||
|
|
||||||
interface NavLink {
|
interface NavLink {
|
||||||
title: string
|
title: string
|
||||||
label?: string
|
label?: string
|
||||||
icon: LucideIcon
|
icon: LucideIcon
|
||||||
variant: "default" | "ghost"
|
variant: "default" | "ghost"
|
||||||
}
|
}
|
||||||
|
|
||||||
interface MailProps {
|
interface MailProps {
|
||||||
accounts: Account[]
|
accounts: Account[]
|
||||||
mails: Mail[]
|
mails: Mail[]
|
||||||
defaultLayout?: number[]
|
defaultLayout?: number[]
|
||||||
defaultCollapsed?: boolean
|
defaultCollapsed?: boolean
|
||||||
navCollapsedSize: number
|
navCollapsedSize: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function MailComponent({
|
function MailComponent({
|
||||||
accounts,
|
accounts,
|
||||||
mails,
|
mails,
|
||||||
defaultLayout = [20, 32, 48],
|
defaultLayout = [20, 32, 48],
|
||||||
defaultCollapsed = false,
|
defaultCollapsed = false,
|
||||||
navCollapsedSize,
|
navCollapsedSize,
|
||||||
}: MailProps) {
|
}: MailProps) {
|
||||||
const [isCollapsed, setIsCollapsed] = React.useState(defaultCollapsed)
|
const [isCollapsed, setIsCollapsed] = React.useState(defaultCollapsed)
|
||||||
const [mail, setMail] = useMail()
|
const [mail, setMail] = useMail()
|
||||||
|
|
||||||
|
@ -174,9 +174,9 @@ function MailComponent({
|
||||||
</ResizablePanelGroup>
|
</ResizablePanelGroup>
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function AccountSwitcher({ isCollapsed, accounts }: { isCollapsed: boolean, accounts: Account[] }) {
|
function AccountSwitcher({ isCollapsed, accounts }: { isCollapsed: boolean, accounts: Account[] }) {
|
||||||
const [selectedAccount, setSelectedAccount] = React.useState(accounts[0].email)
|
const [selectedAccount, setSelectedAccount] = React.useState(accounts[0].email)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -207,9 +207,9 @@ function AccountSwitcher({ isCollapsed, accounts }: { isCollapsed: boolean, acco
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function Nav({ links, isCollapsed }: { links: NavLink[], isCollapsed: boolean }) {
|
function Nav({ links, isCollapsed }: { links: NavLink[], isCollapsed: boolean }) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
data-collapsed={isCollapsed}
|
data-collapsed={isCollapsed}
|
||||||
|
@ -265,9 +265,9 @@ function Nav({ links, isCollapsed }: { links: NavLink[], isCollapsed: boolean })
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function MailList({ items }: { items: Mail[] }) {
|
function MailList({ items }: { items: Mail[] }) {
|
||||||
const [mail, setMail] = useMail()
|
const [mail, setMail] = useMail()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -311,9 +311,9 @@ function MailList({ items }: { items: Mail[] }) {
|
||||||
</div>
|
</div>
|
||||||
</ScrollArea>
|
</ScrollArea>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function MailDisplay({ mail }: { mail: Mail | null }) {
|
function MailDisplay({ mail }: { mail: Mail | null }) {
|
||||||
const today = new Date()
|
const today = new Date()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -490,18 +490,18 @@ function MailDisplay({ mail }: { mail: Mail | null }) {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function getBadgeVariantFromLabel(label: string) {
|
function getBadgeVariantFromLabel(label: string) {
|
||||||
if (["work"].includes(label.toLowerCase())) return "default"
|
if (["work"].includes(label.toLowerCase())) return "default"
|
||||||
if (["personal"].includes(label.toLowerCase())) return "outline"
|
if (["personal"].includes(label.toLowerCase())) return "outline"
|
||||||
return "secondary"
|
return "secondary"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export default function MailPage() {
|
export default function MailPage() {
|
||||||
const layout = [20, 32, 48]; //cookies().get("react-resizable-panels:layout:mail")
|
const layout = [20, 32, 48]; //cookies().get("react-resizable-panels:layout:mail")
|
||||||
const collapsed = false; //cookies().get("react-resizable-panels:collapsed")
|
const collapsed = false; //cookies().get("react-resizable-panels:collapsed")
|
||||||
|
|
||||||
|
@ -522,4 +522,4 @@ export default function MailPage() {
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue