feat: add login button animation, add donation env var+button, ui tweaks, session checking in account links card

This commit is contained in:
Aidan 2025-04-09 01:11:28 -04:00
parent 4c1a20407e
commit 152f96f0af
9 changed files with 111 additions and 47 deletions

View File

@ -2,9 +2,10 @@ import Link from "next/link"
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardHeader, CardTitle, CardFooter } from "@/components/ui/card"
import { auth, signIn } from "@/auth"
import { redirect } from "next/navigation";
import { redirect } from "next/navigation"
import { SiAuthentik } from "react-icons/si"
import { UserPlus } from "lucide-react"
import * as motion from "motion/react-client"
export default async function Login() {
const session = await auth()
@ -27,22 +28,43 @@ export default async function Login() {
await signIn("authentik", { redirectTo: "/account/dashboard" })
}}
>
<Button type="submit" className="w-full">
<motion.div
initial={{ scale: 0.95 }}
animate={{ scale: 1 }}
whileTap={{ scale: 0.95 }}
transition={{ duration: 0.2 }}
>
<Button type="submit" className="w-full cursor-pointer">
<SiAuthentik />
Sign in with Authentik
</Button>
</motion.div>
{process.env.SIGNUP_ENABLED === "true" ? (
<Link href="/account/signup">
<Button variant="outline" className="w-full">
<motion.div
initial={{ scale: 0.95 }}
animate={{ scale: 1 }}
whileTap={{ scale: 0.95 }}
transition={{ duration: 0.2 }}
>
<Button variant="outline" className="w-full cursor-pointer">
<UserPlus />
Create an Account
</Button>
</motion.div>
</Link>
) : (
<motion.div
initial={{ scale: 0.95 }}
animate={{ scale: 1 }}
whileTap={{ scale: 0.95 }}
transition={{ duration: 0.2 }}
>
<Button variant="outline" className="w-full cursor-not-allowed" disabled>
<UserPlus />
Registration is Closed
</Button>
</motion.div>
)}
</form>
</CardContent>

View File

@ -2,12 +2,15 @@
import { ThemeProvider } from "next-themes"
import type { ReactNode } from "react"
import { SessionProvider } from "next-auth/react"
export function Providers({ children }: { children: ReactNode }) {
return (
<SessionProvider>
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
{children}
</ThemeProvider>
</SessionProvider>
)
}

View File

@ -178,7 +178,7 @@ export function LinkGitea({ linked }: { linked: boolean }) {
</Alert>
)}
<p className="text-sm mb-4">
Unlinking your Gitea account will not delete your Gitea account. You can delete your Gitea account <Link href="https://try.gitea.com/user/sign_up" target="_blank" className="text-blue-500">here</Link>.
Unlinking your Gitea account will not delete your Gitea account. You can delete your Gitea account <Link href="https://try.gitea.com/user/sign_up" target="_blank" className="underline hover:text-muted-foreground">here</Link>.
</p>
{unlinkLoading ? (
<Button variant="destructive" disabled>

View File

@ -1,13 +1,25 @@
import { useState, useEffect } from "react";
import { Card, CardHeader, CardTitle, CardDescription, CardContent } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Loader2 } from "lucide-react";
"use client"
import { useState, useEffect } from "react"
import { Card, CardHeader, CardTitle, CardDescription, CardContent } from "@/components/ui/card"
import { Badge } from "@/components/ui/badge"
import { Loader2 } from "lucide-react"
import { useSession } from "next-auth/react"
export const LinkedAccounts = () => {
const [gitStatus, setGitStatus] = useState(false)
const [isLoading, setIsLoading] = useState(false)
const [isAdmin, setIsAdmin] = useState(false)
const [error, setError] = useState<string | null>(null)
const [authStatus, setAuthStatus] = useState(false)
const { data: session } = useSession()
useEffect(() => {
if (session?.user?.email) {
setAuthStatus(true)
}
}, [session])
useEffect(() => {
const fetchGitStatus = async () => {
@ -40,17 +52,32 @@ export const LinkedAccounts = () => {
}
};
fetchGitStatus().then(r => r)
fetchGitStatus()
}, []);
return (
<Card className="col-span-full md:col-span-1">
<CardHeader>
<CardTitle>Linked Accounts</CardTitle>
<CardDescription>LibreCloud-connected services</CardDescription>
<CardDescription>LibreCloud-connected services you've linked to your account.</CardDescription>
</CardHeader>
<CardContent>
<ul className="space-y-2">
{authStatus ? (
<li className="flex items-center">
<span className="w-2 h-2 rounded-full bg-green-500 mr-2"></span>
<span>LibreCloud Auth</span>
</li>
) : (
<li className="flex items-center">
<span className="w-2 h-2 rounded-full bg-red-500 mr-2"></span>
<span>LibreCloud Auth</span>
</li>
)}
<li className="flex items-center">
<span className="w-2 h-2 rounded-full bg-green-500 mr-2"></span>
<span>LibreCloud Mail</span>
</li>
<li className="flex items-center">
{isLoading ? (
<Loader2 className="w-4 h-4 mr-2 animate-spin" />
@ -74,10 +101,6 @@ export const LinkedAccounts = () => {
<span>LibreCloud Git</span>
)}
</li>
<li className="flex items-center">
<span className="w-2 h-2 rounded-full bg-green-500 mr-2"></span>
<span>p0ntus mail</span>
</li>
</ul>
<div className="mt-4">
{error && <p className="text-red-500">{error}</p>}

View File

@ -2,7 +2,8 @@ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { Button } from "@/components/ui/button"
import {
Mail,
Headset
Headset,
Heart
} from "lucide-react"
import Link from "next/link"
@ -17,7 +18,8 @@ export const QuickLinks = () => {
href="/account/dashboard/support"
>
<Button
className="w-full mb-2"
variant="secondary"
className="w-full mb-2 cursor-pointer"
>
<Headset />
Support
@ -27,12 +29,24 @@ export const QuickLinks = () => {
href="https://mail.librecloud.cc"
>
<Button
className="w-full mb-2"
variant="secondary"
className="w-full mb-2 cursor-pointer"
>
<Mail />
Webmail
</Button>
</Link>
<Link
href={process.env.NEXT_PUBLIC_DONATE_URL || "https://donate.stripe.com/6oE8yxaPk6yXbpS145"}
>
<Button
variant="secondary"
className="w-full mb-2 cursor-pointer"
>
<Heart />
Donate
</Button>
</Link>
</CardContent>
</Card>
);

View File

@ -36,7 +36,7 @@ export const WelcomeCard = () => {
<p className="text-sm mt-4">Thats all, have a great day!</p>
</CardContent>
<CardFooter>
<Button className="w-full" onClick={handleMarkAsRead}>
<Button className="w-full cursor-pointer" onClick={handleMarkAsRead}>
<Check /> Mark as Read
</Button>
</CardFooter>

View File

@ -1,7 +1,7 @@
import Link from "next/link"
import { Mail, Key, ExternalLink } from "lucide-react"
import { SiGitea, SiAuthentik } from "react-icons/si";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Card, CardFooter, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Button } from "@/components/ui/button"
export const ServicesTab = () => (
@ -13,16 +13,16 @@ export const ServicesTab = () => (
<Mail className="mr-2 h-4 w-4" />
Webmail
</CardTitle>
<CardDescription className="pt-4">Send, read, and manage your email account from a web browser!</CardDescription>
<CardDescription className="pt-4">Send, read, and manage your email account from a web browser! Powered by Roundcube and LibreCloud Mail.</CardDescription>
</CardHeader>
<CardContent>
<CardFooter>
<Button>
<ExternalLink className="h-4 w-4" />
<Link href="https://mail.librecloud.cc/">
Open App
</Link>
</Button>
</CardContent>
</CardFooter>
</Card>
<Card>
@ -31,16 +31,16 @@ export const ServicesTab = () => (
<SiGitea className="mr-2 h-4 w-4" />
Git
</CardTitle>
<CardDescription className="pt-4">Host your repositories and run Actions on a fair usage policy.</CardDescription>
<CardDescription className="pt-4">Host unlimited repositories and run Actions on our Git server, powered by Gitea.</CardDescription>
</CardHeader>
<CardContent>
<CardFooter>
<Button>
<ExternalLink className="h-4 w-4" />
<Link href="https://git.pontusmail.org/">
Open App
</Link>
</Button>
</CardContent>
</CardFooter>
</Card>
<Card>
@ -49,16 +49,16 @@ export const ServicesTab = () => (
<Key className="mr-2 h-4 w-4" />
Pass
</CardTitle>
<CardDescription className="pt-4">Securely store your passwords, notes, and 2FA codes with Vaultwarden.</CardDescription>
<CardDescription className="pt-4">Securely store your passwords, notes, and 2FA codes with Vaultwarden. Data is encrypted at rest.</CardDescription>
</CardHeader>
<CardContent>
<CardFooter>
<Button>
<ExternalLink className="h-4 w-4" />
<Link href="https://vaultwarden.p0ntus.com/">
<Link href="https://pass.librecloud.cc/">
Open App
</Link>
</Button>
</CardContent>
</CardFooter>
</Card>
<Card>
@ -69,14 +69,14 @@ export const ServicesTab = () => (
</CardTitle>
<CardDescription className="pt-4">Manage your single-sign-on account for all LibreCloud services.</CardDescription>
</CardHeader>
<CardContent>
<CardFooter>
<Button>
<ExternalLink className="h-4 w-4" />
<Link href="https://auth.librecloud.cc/">
Open App
</Link>
</Button>
</CardContent>
</CardFooter>
</Card>
</div>
)

View File

@ -10,8 +10,9 @@ These are the environment variables which handle how `librecloud/web` functions.
With these variables, you can disable entire parts of the dashboard, such as registration.
| Environment Variable | Description | Expected Value |
|----------------------|-----------------------------------------------------------|----------------------------------------|
|------------------------|-----------------------------------------------------------|----------------------------------------|
| SIGNUP_ENABLED | Controls if the signup page and APIs are enabled/disabled | `true` (Enabled) or `false` (Disabled) |
| NEXT_PUBLIC_DONATE_URL | Changes the universal donation link for buttons/links | String - `https://...` |
## Authentik

View File

@ -29,6 +29,7 @@
"clsx": "^2.1.1",
"cmdk": "1.0.0",
"cookies-next": "^5.1.0",
"framer-motion": "^12.6.3",
"geist": "^1.3.1",
"js-cookie": "^3.0.5",
"lucide-react": "^0.474.0",