design: improved footer and profile card
All checks were successful
Build and Push Docker Image / build_and_push (push) Successful in 4s
Build and Push Nightly CI Image / build_and_push (push) Successful in 50s
Bump Dependencies / update-dependencies (push) Successful in 1m26s

This commit is contained in:
Aidan 2025-02-21 00:01:34 -05:00
parent ddf16ef013
commit c96c2b8c5f
2 changed files with 87 additions and 45 deletions

View File

@ -1,60 +1,89 @@
"use client"; "use client"
import { Card, CardHeader, CardTitle, CardDescription, CardContent } from "@/components/ui/card"; import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card"
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 { Users, Clock, User } from "lucide-react"; import { Users, Clock, User, Mail } from "lucide-react"
import { Separator } from "@/components/ui/separator"
interface DashboardState { interface DashboardState {
gitUser: string; gitUser: string
gitAvatar?: string; gitAvatar?: string
gitLastLogin?: string; gitLastLogin?: string
gitFollowerCt: number; gitFollowerCt: number
gitFollowingCt: number; gitFollowingCt: number
gitIsAdmin: boolean; gitIsAdmin: boolean
gitEmail?: string; gitEmail?: string
} }
export function GiteaProfileCard({ dashboardState }: { dashboardState: DashboardState }) { export function GiteaProfileCard({ dashboardState }: { dashboardState: DashboardState }) {
const convDate = (dateStr: string) => { const convDate = (dateStr: string) => {
const date = new Date(dateStr); const date = new Date(dateStr)
return date.toLocaleString(); return date.toLocaleString()
} }
return ( return (
<Card> <Card className="overflow-hidden transition-all hover:shadow-lg">
<CardHeader> <CardHeader className="pb-2">
<CardTitle>Profile</CardTitle> <div className="flex items-center justify-between">
<CardDescription>An overview of your LibreCloud Git account</CardDescription> <CardTitle className="text-xl font-semibold">Profile</CardTitle>
{dashboardState.gitIsAdmin && (
<Badge variant="secondary" className="h-6">
Admin
</Badge>
)}
</div>
</CardHeader> </CardHeader>
<CardContent className="space-y-4"> <CardContent className="space-y-6">
<div className="flex items-center space-x-4"> <div className="flex flex-col gap-6 sm:flex-row sm:items-center sm:gap-8">
<Avatar className="w-20 h-20"> <Avatar className="h-24 w-24 shrink-0 border-2 border-border">
<AvatarImage src={dashboardState.gitAvatar || ""} /> <AvatarImage src={dashboardState.gitAvatar || ""} alt={dashboardState.gitUser} />
<AvatarFallback> <AvatarFallback className="bg-muted">
<User className="w-10 h-10" /> <User className="h-12 w-12 text-muted-foreground" />
</AvatarFallback> </AvatarFallback>
</Avatar> </Avatar>
<div> <div className="space-y-4">
<h3 className="text-2xl font-semibold flex items-center"> <h3 className="text-2xl font-bold tracking-tight">{dashboardState.gitUser}</h3>
{dashboardState.gitUser} <div className="flex flex-wrap items-center gap-4">
{dashboardState.gitIsAdmin && <Badge className="ml-2">Admin</Badge>} <div className="flex items-center gap-1.5">
</h3> <div className="flex h-8 w-8 items-center justify-center rounded-full bg-primary/10">
<div className="flex space-x-4 text-sm text-muted-foreground"> <Users className="h-4 w-4 text-primary" />
<span className="flex items-center"> </div>
<Users className="w-4 h-4 mr-1" /> {dashboardState.gitFollowerCt} followers <div className="text-sm">
</span> <p className="font-medium">{dashboardState.gitFollowerCt}</p>
<span className="flex items-center"> <p className="text-xs text-muted-foreground">Followers</p>
<Users className="w-4 h-4 mr-1" /> {dashboardState.gitFollowingCt} following </div>
</span> </div>
<div className="flex items-center gap-1.5">
<div className="flex h-8 w-8 items-center justify-center rounded-full bg-primary/10">
<Users className="h-4 w-4 text-primary" />
</div>
<div className="text-sm">
<p className="font-medium">{dashboardState.gitFollowingCt}</p>
<p className="text-xs text-muted-foreground">Following</p>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
<div className="flex items-center space-x-2"> <Separator />
<Clock className="w-4 h-4" /> <div className="flex items-center gap-2 text-sm text-muted-foreground">
<span>Last login: {dashboardState.gitLastLogin === "Never" ? "Never" : (dashboardState.gitLastLogin && convDate(dashboardState.gitLastLogin)) || "N/A"}</span> <Clock className="h-4 w-4" />
<span>
Last login:{" "}
{dashboardState.gitLastLogin === "Never"
? "Never"
: (dashboardState.gitLastLogin && convDate(dashboardState.gitLastLogin)) || "N/A"}
</span>
</div>
<div className="flex items-center gap-2 text-sm text-muted-foreground">
<Mail className="h-4 w-4" />
<span>
Email: {dashboardState.gitEmail || "N/A"}
</span>
</div> </div>
</CardContent> </CardContent>
</Card> </Card>
) )
} }

View File

@ -1,6 +1,7 @@
"use client" "use client"
import {useEffect, useState} from "react" import { useEffect, useState } from "react"
import { TbNoCopyright } from "react-icons/tb";
export function Footer() { export function Footer() {
const [renderTime, setRenderTime] = useState<number | null>(null) const [renderTime, setRenderTime] = useState<number | null>(null)
@ -18,11 +19,23 @@ export function Footer() {
return ( return (
<footer className="py-2 px-4 text-sm text-muted-foreground bg-muted"> <footer className="py-2 px-4 text-sm text-muted-foreground bg-muted">
<div className="flex justify-between"> <div className="flex flex-col gap-2 md:flex-row md:items-center md:justify-between">
<p>Created by a community, not a company.</p> <div className="flex items-center justify-center">
{renderTime !== null ? <p>Page rendered in {renderTime.toFixed(2)} ms</p> : <p>Calculating render time...</p>} <TbNoCopyright className="mr-2" />
<p className="text-center md:text-left">
Created by a community, not a company.
</p>
</div>
{renderTime !== null ? (
<p className="text-center md:text-right">
Page rendered in {renderTime.toFixed(2)} ms
</p>
) : (
<p className="text-center md:text-right">
Calculating render time...
</p>
)}
</div> </div>
</footer> </footer>
) )
} }