From 4f4e73318a59e97c79420fe8c2be804cc963bb45 Mon Sep 17 00:00:00 2001 From: SomeCodecat <88855796+SomeCodecat@users.noreply.github.com> Date: Wed, 21 May 2025 16:42:48 +0200 Subject: [PATCH] feat(ui): Improve login card design and theme customization Refactor the `Button` component, add new `LoginCard` component, update `ThemePicker` component, edit global CSS styles to include card background and foreground and style the login page, including the logo and login form. --- src/app/globals.css | 22 ++--- src/app/login/page.tsx | 19 ++--- src/app/logout/page.tsx | 2 +- src/app/settings/page.tsx | 2 +- src/components/{ui => custom-ui}/button.tsx | 3 +- src/components/custom-ui/login-card.tsx | 92 +++++++++++++++++++++ src/components/icon-button.tsx | 4 +- src/components/user/login-form.tsx | 2 +- src/components/user/redirect-button.tsx | 2 +- src/components/user/sso-login-button.tsx | 1 - src/components/user/theme-picker.tsx | 2 +- 11 files changed, 122 insertions(+), 29 deletions(-) rename src/components/{ui => custom-ui}/button.tsx (98%) create mode 100644 src/components/custom-ui/login-card.tsx diff --git a/src/app/globals.css b/src/app/globals.css index a7bbb2b..558d875 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -39,6 +39,8 @@ --active-secondary: oklch(0.4254 0.133 272.15); --disabled-secondary: oklch(0.4937 0.1697 271.26 / 0.5); + --card: var(--neutral-800); + /* ------------------- */ --foreground: oklch(0.13 0.028 261.692); @@ -99,7 +101,7 @@ } @theme inline { - --transparent: var(--transpatent); + --transparent: var(--transparent); --color-neutral-000: var(--neutral-000); --color-neutral-100: var(--neutral-100); @@ -114,12 +116,12 @@ --color-neutral-800: var(--neutral-800); --color-neutral-900: var(--neutral-900); - --background: var(--neutral-750); - --base: var(--neutral-800); - --text: var(--neutral-000); - --text-alt: var(--neutral-900); - --background-disabled: var(--neutral-500); - --text-disabled: var(--neutral-700); + --color-background: var(--neutral-750); + --color-base: var(--neutral-800); + --color-text: var(--text); + --color-text-alt: var(--text-alt); + --color-background-disabled: var(--neutral-500); + --color-text-disabled: var(--neutral-700); --radius: 0.688rem; --color-primary: var(--primary); @@ -224,7 +226,7 @@ --neutral-900: oklch(0 0 0); --background: var(--neutral-750); - --base: var(--neutral-800); + --base: var(--neutral-750); --text: var(--neutral-000); --text-alt: var(--neutral-900); --background-disabled: var(--neutral-500); @@ -240,12 +242,12 @@ --active-secondary: oklch(0.4471 0.15 271.61); --disabled-secondary: oklch(0.6065 0.213 271.11 / 0.4); + --card: var(--neutral-750); + /* ------------------- */ --foreground: oklch(0.985 0.002 247.839); - --card: oklch(0.21 0.034 264.665); - --card-foreground: oklch(0.985 0.002 247.839); --popover: oklch(0.21 0.034 264.665); diff --git a/src/app/login/page.tsx b/src/app/login/page.tsx index 3049198..f49fb8f 100644 --- a/src/app/login/page.tsx +++ b/src/app/login/page.tsx @@ -2,13 +2,17 @@ import { auth, providerMap } from '@/auth'; import SSOLogin from '@/components/user/sso-login-button'; import LoginForm from '@/components/user/login-form'; import { redirect } from 'next/navigation'; -import { Button } from '@/components/ui/button'; +import { Button } from '@/components/custom-ui/button'; import Image from 'next/image'; import { Separator } from '@/components/custom-ui/separator'; import Logo from '@/components/logo'; import '@/app/globals.css'; -import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; +import { + Card, + CardContent, + CardHeader, +} from '@/components/custom-ui/login-card'; import { ThemePicker } from '@/components/user/theme-picker'; import { HoverCard, @@ -30,14 +34,9 @@ export default async function LoginPage() {
- - - + + + diff --git a/src/app/logout/page.tsx b/src/app/logout/page.tsx index 15f29aa..c819a45 100644 --- a/src/app/logout/page.tsx +++ b/src/app/logout/page.tsx @@ -1,5 +1,5 @@ import { signOut } from '@/auth'; -import { Button } from '@/components/ui/button'; +import { Button } from '@/components/custom-ui/button'; import { Card, CardContent, diff --git a/src/app/settings/page.tsx b/src/app/settings/page.tsx index 45974fb..9afe7c6 100644 --- a/src/app/settings/page.tsx +++ b/src/app/settings/page.tsx @@ -1,4 +1,4 @@ -import { Button } from '@/components/ui/button'; +import { Button } from '@/components/custom-ui/button'; import { Card, CardContent, diff --git a/src/components/ui/button.tsx b/src/components/custom-ui/button.tsx similarity index 98% rename from src/components/ui/button.tsx rename to src/components/custom-ui/button.tsx index f47a756..51f3b63 100644 --- a/src/components/ui/button.tsx +++ b/src/components/custom-ui/button.tsx @@ -15,8 +15,9 @@ const buttonVariants = cva( 'bg-secondary text-text-alt shadow-xs hover:bg-hover-secondary active:bg-active-secondary', outline: 'border-2 border-primary bg-transparent text-text shadow-xs hover:bg-primary hover:border-neutral-000 hover:border-1.5 hover:text-neutral-000 active:bg-active-primary', - destructive: + /*destructive: 'bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60', + */ ghost: 'hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50', link: 'text-text underline-offset-4 hover:underline', diff --git a/src/components/custom-ui/login-card.tsx b/src/components/custom-ui/login-card.tsx new file mode 100644 index 0000000..616a45c --- /dev/null +++ b/src/components/custom-ui/login-card.tsx @@ -0,0 +1,92 @@ +import * as React from 'react'; + +import { cn } from '@/lib/utils'; + +function Card({ className, ...props }: React.ComponentProps<'div'>) { + return ( +
+ ); +} + +function CardHeader({ className, ...props }: React.ComponentProps<'div'>) { + return ( +
+ ); +} + +function CardTitle({ className, ...props }: React.ComponentProps<'div'>) { + return ( +
+ ); +} + +function CardDescription({ className, ...props }: React.ComponentProps<'div'>) { + return ( +
+ ); +} + +function CardAction({ className, ...props }: React.ComponentProps<'div'>) { + return ( +
+ ); +} + +function CardContent({ className, ...props }: React.ComponentProps<'div'>) { + return ( +
+ ); +} + +function CardFooter({ className, ...props }: React.ComponentProps<'div'>) { + return ( +
+ ); +} + +export { + Card, + CardHeader, + CardFooter, + CardTitle, + CardAction, + CardDescription, + CardContent, +}; diff --git a/src/components/icon-button.tsx b/src/components/icon-button.tsx index 8888b6b..ad67eaa 100644 --- a/src/components/icon-button.tsx +++ b/src/components/icon-button.tsx @@ -1,4 +1,4 @@ -import { Button } from '@/components/ui/button'; +import { Button } from '@/components/custom-ui/button'; import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; @@ -12,7 +12,7 @@ export function IconButton({ children: React.ReactNode; } & React.ComponentProps) { return ( - diff --git a/src/components/user/login-form.tsx b/src/components/user/login-form.tsx index a2ab6c9..ec7b8c1 100644 --- a/src/components/user/login-form.tsx +++ b/src/components/user/login-form.tsx @@ -1,6 +1,6 @@ import { signIn } from '@/auth'; import LabeledInput from '@/components/labeled-input'; -import { Button } from '@/components/ui/button'; +import { Button } from '@/components/custom-ui/button'; import { AuthError } from 'next-auth'; import { redirect } from 'next/navigation'; diff --git a/src/components/user/redirect-button.tsx b/src/components/user/redirect-button.tsx index c4bf997..e4f8a62 100644 --- a/src/components/user/redirect-button.tsx +++ b/src/components/user/redirect-button.tsx @@ -1,4 +1,4 @@ -import { Button } from '../ui/button'; +import { Button } from '../custom-ui/button'; import Link from 'next/link'; export function RedirectButton({ diff --git a/src/components/user/sso-login-button.tsx b/src/components/user/sso-login-button.tsx index 09a76f6..76eac83 100644 --- a/src/components/user/sso-login-button.tsx +++ b/src/components/user/sso-login-button.tsx @@ -22,7 +22,6 @@ export default function SSOLogin({ type='submit' variant='secondary' icon={faOpenid} - icon={faOpenid} > Login with {providerDisplayName} diff --git a/src/components/user/theme-picker.tsx b/src/components/user/theme-picker.tsx index 5341c3c..37a2ceb 100644 --- a/src/components/user/theme-picker.tsx +++ b/src/components/user/theme-picker.tsx @@ -4,7 +4,7 @@ import * as React from 'react'; import { Moon, Sun } from 'lucide-react'; import { useTheme } from 'next-themes'; -import { Button } from '@/components/ui/button'; +import { Button } from '@/components/custom-ui/button'; import { DropdownMenu, DropdownMenuContent,