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
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:
parent
ddf16ef013
commit
c96c2b8c5f
@ -1,60 +1,89 @@
|
||||
"use client";
|
||||
"use client"
|
||||
|
||||
import { Card, CardHeader, CardTitle, CardDescription, CardContent } from "@/components/ui/card";
|
||||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Users, Clock, User } from "lucide-react";
|
||||
import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card"
|
||||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
|
||||
import { Badge } from "@/components/ui/badge"
|
||||
import { Users, Clock, User, Mail } from "lucide-react"
|
||||
import { Separator } from "@/components/ui/separator"
|
||||
|
||||
interface DashboardState {
|
||||
gitUser: string;
|
||||
gitAvatar?: string;
|
||||
gitLastLogin?: string;
|
||||
gitFollowerCt: number;
|
||||
gitFollowingCt: number;
|
||||
gitIsAdmin: boolean;
|
||||
gitEmail?: string;
|
||||
gitUser: string
|
||||
gitAvatar?: string
|
||||
gitLastLogin?: string
|
||||
gitFollowerCt: number
|
||||
gitFollowingCt: number
|
||||
gitIsAdmin: boolean
|
||||
gitEmail?: string
|
||||
}
|
||||
|
||||
export function GiteaProfileCard({ dashboardState }: { dashboardState: DashboardState }) {
|
||||
const convDate = (dateStr: string) => {
|
||||
const date = new Date(dateStr);
|
||||
return date.toLocaleString();
|
||||
const date = new Date(dateStr)
|
||||
return date.toLocaleString()
|
||||
}
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Profile</CardTitle>
|
||||
<CardDescription>An overview of your LibreCloud Git account</CardDescription>
|
||||
<Card className="overflow-hidden transition-all hover:shadow-lg">
|
||||
<CardHeader className="pb-2">
|
||||
<div className="flex items-center justify-between">
|
||||
<CardTitle className="text-xl font-semibold">Profile</CardTitle>
|
||||
{dashboardState.gitIsAdmin && (
|
||||
<Badge variant="secondary" className="h-6">
|
||||
Admin
|
||||
</Badge>
|
||||
)}
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<div className="flex items-center space-x-4">
|
||||
<Avatar className="w-20 h-20">
|
||||
<AvatarImage src={dashboardState.gitAvatar || ""} />
|
||||
<AvatarFallback>
|
||||
<User className="w-10 h-10" />
|
||||
<CardContent className="space-y-6">
|
||||
<div className="flex flex-col gap-6 sm:flex-row sm:items-center sm:gap-8">
|
||||
<Avatar className="h-24 w-24 shrink-0 border-2 border-border">
|
||||
<AvatarImage src={dashboardState.gitAvatar || ""} alt={dashboardState.gitUser} />
|
||||
<AvatarFallback className="bg-muted">
|
||||
<User className="h-12 w-12 text-muted-foreground" />
|
||||
</AvatarFallback>
|
||||
</Avatar>
|
||||
<div>
|
||||
<h3 className="text-2xl font-semibold flex items-center">
|
||||
{dashboardState.gitUser}
|
||||
{dashboardState.gitIsAdmin && <Badge className="ml-2">Admin</Badge>}
|
||||
</h3>
|
||||
<div className="flex space-x-4 text-sm text-muted-foreground">
|
||||
<span className="flex items-center">
|
||||
<Users className="w-4 h-4 mr-1" /> {dashboardState.gitFollowerCt} followers
|
||||
</span>
|
||||
<span className="flex items-center">
|
||||
<Users className="w-4 h-4 mr-1" /> {dashboardState.gitFollowingCt} following
|
||||
</span>
|
||||
<div className="space-y-4">
|
||||
<h3 className="text-2xl font-bold tracking-tight">{dashboardState.gitUser}</h3>
|
||||
<div className="flex flex-wrap items-center gap-4">
|
||||
<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.gitFollowerCt}</p>
|
||||
<p className="text-xs text-muted-foreground">Followers</p>
|
||||
</div>
|
||||
</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 className="flex items-center space-x-2">
|
||||
<Clock className="w-4 h-4" />
|
||||
<span>Last login: {dashboardState.gitLastLogin === "Never" ? "Never" : (dashboardState.gitLastLogin && convDate(dashboardState.gitLastLogin)) || "N/A"}</span>
|
||||
<Separator />
|
||||
<div className="flex items-center gap-2 text-sm text-muted-foreground">
|
||||
<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>
|
||||
</CardContent>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
"use client"
|
||||
|
||||
import {useEffect, useState} from "react"
|
||||
import { useEffect, useState } from "react"
|
||||
import { TbNoCopyright } from "react-icons/tb";
|
||||
|
||||
export function Footer() {
|
||||
const [renderTime, setRenderTime] = useState<number | null>(null)
|
||||
@ -18,11 +19,23 @@ export function Footer() {
|
||||
|
||||
return (
|
||||
<footer className="py-2 px-4 text-sm text-muted-foreground bg-muted">
|
||||
<div className="flex justify-between">
|
||||
<p>Created by a community, not a company.</p>
|
||||
{renderTime !== null ? <p>Page rendered in {renderTime.toFixed(2)} ms</p> : <p>Calculating render time...</p>}
|
||||
<div className="flex flex-col gap-2 md:flex-row md:items-center md:justify-between">
|
||||
<div className="flex items-center justify-center">
|
||||
<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>
|
||||
</footer>
|
||||
)
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user