feat: dark theme support

This commit is contained in:
2025-05-24 16:15:22 +02:00
parent 1a596eef87
commit 587a463623
6 changed files with 136 additions and 56 deletions

View File

@ -6,7 +6,7 @@ export const Input: FC<InputProps> = ({ className, ...props }) => {
return ( return (
<input <input
{...props} {...props}
className={`w-full border border-gray-300 rounded-md px-3 py-3 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 ${ className={`w-full border border-gray-300 dark:border-gray-600 dark:placeholder-gray-600 dark:text-gray-100 rounded-md px-3 py-3 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 ${
className || "" className || ""
}`} }`}
/> />

View File

@ -1,6 +1,6 @@
import { useDbContext } from "@/context/db/db"; import { useDbContext } from "@/context/db/db";
import { type LocalAccount, useAccountRepo } from "@/repository/account"; import { type LocalAccount, useAccountRepo } from "@/repository/account";
import { User } from "lucide-react"; import { CirclePlus, User } from "lucide-react";
import { useEffect, useState, type FC } from "react"; import { useEffect, useState, type FC } from "react";
const AccountList: FC = () => { const AccountList: FC = () => {
@ -20,7 +20,7 @@ const AccountList: FC = () => {
<div role="status"> <div role="status">
<svg <svg
aria-hidden="true" aria-hidden="true"
className="w-12 h-12 text-gray-200 animate-spin fill-blue-600" className="w-12 h-12 text-gray-200 dark:text-gray-600 animate-spin fill-blue-600"
viewBox="0 0 100 101" viewBox="0 0 100 101"
fill="none" fill="none"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
@ -40,22 +40,40 @@ const AccountList: FC = () => {
); );
} }
return accounts.map((account) => ( return (
<>
{accounts.map((account) => (
<div <div
key={account.accountId} key={account.accountId}
className="flex flex-row items-center p-4 border-gray-200 border sm:border-l sm:border-r border-r-0 border-l-0 sm:rounded-xl select-none cursor-pointer hover:bg-gray-50 transition-colors mb-2" className="flex flex-row items-center p-4 border-gray-200 dark:border-gray-700/65 border-b border-r-0 border-l-0 select-none cursor-pointer hover:bg-gray-50/50 dark:hover:bg-gray-800/10 transition-colors mb-0"
> >
<div> <div>
<div className="rounded-full p-2 bg-gray-100 mr-3"> <div className="rounded-full p-2 bg-gray-100 dark:bg-gray-700 text-gray-900 dark:text-gray-200 mr-3 ring ring-gray-900 dark:ring dark:ring-gray-100">
<User /> <User />
</div> </div>
</div> </div>
<div className="flex flex-col"> <div className="flex flex-col">
<p className="text-base">{account.label}</p> <p className="text-base text-gray-900 dark:text-gray-200">
<p className="text-gray-500 text-sm">{account.email}</p> {account.label}
</p>
<p className="text-gray-500 dark:text-gray-600 text-sm">
{account.email}
</p>
</div> </div>
</div> </div>
)); ))}
<div className="flex flex-row items-center p-4 border-gray-200 dark:border-gray-700/65 border-b border-r-0 border-l-0 select-none cursor-pointer hover:bg-gray-50/50 dark:hover:bg-gray-800/10 transition-colors mb-0">
<div>
<div className="rounded-full p-2 text-gray-900 dark:text-gray-200 mr-3">
<CirclePlus />
</div>
</div>
<p className="text-base text-gray-900 dark:text-gray-200">
Add new account
</p>
</div>
</>
);
}; };
export default AccountList; export default AccountList;

View File

@ -1,39 +1,102 @@
import { type FC } from "react"; import { type FC } from "react";
import overlay from "@/assets/overlay.jpg";
import { Card, CardContent } from "@/components/ui/card"; import { Card, CardContent } from "@/components/ui/card";
import AccountList from "@/feature/AccountList"; import { ArrowLeftRight, User } from "lucide-react";
import { Button } from "@/components/ui/button";
const AgreementPage: FC = () => { const AgreementPage: FC = () => {
return ( return (
<div <div
className="relative min-h-screen bg-cover bg-center bg-white" className={`relative min-h-screen bg-cover bg-center bg-white dark:bg-black bg-[url(/overlay.jpg)] dark:bg-[url(dark-overlay.jpg)]`}
style={{ backgroundImage: `url(${overlay})` }}
> >
<div className="relative z-10 flex items-center justify-center min-h-screen"> <div className="relative z-10 flex items-center justify-center min-h-screen">
<Card className="sm:w-[700px] sm:min-w-[700px] sm:max-w-96 sm:min-h-auto p-3 min-h-screen w-full min-w-full shadow-lg bg-white/90 backdrop-blur-md"> <Card className="sm:w-[425px] sm:min-w-[425px] sm:max-w-96 sm:min-h-auto p-3 min-h-screen w-full min-w-full shadow-lg bg-white/65 dark:bg-black/65 backdrop-blur-md">
<div className="flex sm:flex-row flex-col sm:items-start items-center pt-16 sm:pt-0"> <div className="flex flex-col items-center pt-10 sm:pt-0">
<div className="flex flex-col items-center flex-5/6"> <div className="flex flex-col items-center flex-5/6">
<img {/* <img
src="/icon.png" src="/icon.png"
alt="icon" alt="icon"
className="w-16 h-16 mb-4 mt-2 sm:mt-6" className="w-16 h-16 mb-4 mt-2 sm:mt-6"
/> */}
<div className="flex flex-row items-center gap-4 mt-2 mb-4 sm:mt-6">
<div className="p-2 bg-gray-100 rounded-full ring ring-gray-900 dark:ring dark:ring-gray-100">
<User size={32} />
</div>
<div className="text-gray-400 dark:text-gray-600">
{/* <Activity /> */}
<ArrowLeftRight />
</div>
<div className="p-2 rounded-full bg-gray-900 ring ring-gray-900 dark:ring dark:ring-gray-100">
{/* <img
src="https://lucide.dev/logo.dark.svg"
className="w-8 h-8"
/> */}
<img
src="https://developer.mozilla.org/favicon.svg"
className="w-8 h-8"
/> />
</div>
</div>
<div className="px-4 sm:mt-4 mt-8"> <div className="px-4 sm:mt-4 mt-8">
<h2 className="text-2xl font-bold text-gray-800 text-left w-full"> <h2 className="text-2xl font-medium text-gray-800 dark:text-gray-300 text-center w-full mb-2">
Select Account <a href="#" className="text-blue-500">
MDN Lab Services
</a>{" "}
wants to access your Home Account
</h2> </h2>
<h4 className="text-base mb-3 text-gray-400 text-left"> <div className="flex flex-row items-center justify-center mb-6 gap-2">
Choose one of the accounts below in order to proceed to home <div className="p-2 bg-gray-100 rounded-full ring ring-gray-900 dark:ring dark:ring-gray-100">
lab services and tools. <User />
</div>
<p className="text-sm text-gray-500 dark:text-gray-500">
qwer.009771@gmail.com
</p>
</div>
<h4 className="text-base mb-3 text-gray-400 dark:text-gray-500 text-left">
This will allow{" "}
<a href="#" className="text-blue-500">
MDN Lab Services
</a>{" "}
to:
</h4> </h4>
</div> </div>
</div> </div>
{/* <LogIn className="w-8 h-8 text-gray-700 mb-4" /> */} {/* <LogIn className="w-8 h-8 text-gray-700 mb-4" /> */}
<CardContent className="w-full space-y-4"> <CardContent className="w-full space-y-4 text-sm">
<AccountList /> <div className="flex flex-col gap-3 mb-8">
<div className="flex flex-row items-center justify-between text-gray-600 dark:text-gray-400">
<div className="flex flex-row items-center gap-4">
<div className="w-3 h-3 rounded-full bg-blue-500"></div>
<p>View your full name, email and profile image</p>
</div>
</div>
<div className="flex flex-row items-center justify-between text-gray-600 dark:text-gray-400">
<div className="flex flex-row items-center gap-4">
<div className="w-3 h-3 rounded-full bg-blue-500"></div>
<p>View your permission from "MDN" group</p>
</div>
</div>
</div>
<div className="mb-10">
<p className="font-medium mb-4 dark:text-gray-200">
Are you sure you want to trust MDN Lab Services?
</p>
<p className="text-sm text-gray-400 dark:text-gray-500">
Please do not share any sensitive, personal, or unnecessary
information unless you trust this service. Protect your
privacy and only provide information that is required for the
intended purpose.
</p>
</div>
<div className="flex flex-row justify-between items-center">
<Button variant="text">Cancel</Button>
<Button>Allow</Button>
</div>
</CardContent> </CardContent>
</div> </div>
</Card> </Card>

View File

@ -1,19 +1,22 @@
import { type FC } from "react"; import { type FC } from "react";
import overlay from "@/assets/overlay.jpg"; // import overlay from "@/assets/overlay.jpg";
// import darkOverlay from "@/assets/dark-overlay.jpg";
import { Card, CardContent } from "@/components/ui/card"; import { Card, CardContent } from "@/components/ui/card";
import AccountList from "@/feature/AccountList"; import AccountList from "@/feature/AccountList";
const IndexPage: FC = () => { const IndexPage: FC = () => {
// console.log(overlay);
return ( return (
<div <div
className="relative min-h-screen bg-cover bg-center bg-white" className={`relative min-h-screen bg-cover bg-center bg-white dark:bg-black bg-[url(/overlay.jpg)] dark:bg-[url(dark-overlay.jpg)]`}
style={{ backgroundImage: `url(${overlay})` }} // style={{ backgroundImage: `url(${overlay})` }}
> >
<div className="relative z-10 flex items-center justify-center min-h-screen"> <div className="relative z-10 flex items-center justify-center min-h-screen">
<Card className="sm:w-[700px] sm:min-w-[700px] sm:max-w-96 sm:min-h-auto p-3 min-h-screen w-full min-w-full shadow-lg bg-white/90 backdrop-blur-md"> <Card className="sm:w-[700px] sm:min-w-[700px] sm:max-w-96 sm:min-h-auto p-3 min-h-screen w-full min-w-full shadow-lg bg-white/65 dark:bg-black/65 backdrop-blur-md">
<div className="flex sm:flex-row flex-col sm:items-stretch items-center pt-16 sm:pt-0"> <div className="flex sm:flex-row flex-col sm:items-stretch items-center pt-16 sm:pt-0">
<div className="flex flex-col items-center flex-5/6"> <div className="flex flex-col items-center flex-1">
<img <img
src="/icon.png" src="/icon.png"
alt="icon" alt="icon"
@ -21,10 +24,10 @@ const IndexPage: FC = () => {
/> />
<div className="px-4 sm:mt-4 mt-8"> <div className="px-4 sm:mt-4 mt-8">
<h2 className="text-2xl font-bold text-gray-800 text-left w-full"> <h2 className="text-2xl font-bold text-gray-800 text-left w-full dark:text-gray-100">
Select Account Select Account
</h2> </h2>
<h4 className="text-base mb-3 text-gray-400 text-left"> <h4 className="text-base mb-3 text-gray-400 text-left dark:text-gray-300">
Choose one of the accounts below in order to proceed to home Choose one of the accounts below in order to proceed to home
lab services and tools. lab services and tools.
</h4> </h4>
@ -32,7 +35,7 @@ const IndexPage: FC = () => {
</div> </div>
{/* <LogIn className="w-8 h-8 text-gray-700 mb-4" /> */} {/* <LogIn className="w-8 h-8 text-gray-700 mb-4" /> */}
<CardContent className="w-full space-y-4"> <CardContent className="w-full space-y-4 flex-1">
<AccountList /> <AccountList />
</CardContent> </CardContent>
</div> </div>

View File

@ -5,7 +5,6 @@ import { Link } from "react-router-dom";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import overlay from "@/assets/overlay.jpg";
import { useForm, type SubmitHandler } from "react-hook-form"; import { useForm, type SubmitHandler } from "react-hook-form";
import { useCallback, useState } from "react"; import { useCallback, useState } from "react";
import { loginApi } from "@/api/login"; import { loginApi } from "@/api/login";
@ -71,11 +70,10 @@ export default function LoginPage() {
return ( return (
<div <div
className="relative min-h-screen bg-cover bg-center bg-white" className={`relative min-h-screen bg-cover bg-center bg-white dark:bg-black bg-[url(/overlay.jpg)] dark:bg-[url(dark-overlay.jpg)]`}
style={{ backgroundImage: `url(${overlay})` }}
> >
<div className="relative z-10 flex items-center justify-center min-h-screen"> <div className="relative z-10 flex items-center justify-center min-h-screen">
<Card className="sm:w-96 sm:min-w-96 sm:max-w-96 sm:min-h-auto p-3 min-h-screen w-full min-w-full shadow-lg bg-white/90 backdrop-blur-md"> <Card className="sm:w-96 sm:min-w-96 sm:max-w-96 sm:min-h-auto p-3 min-h-screen w-full min-w-full shadow-lg bg-white/65 dark:bg-black/70 backdrop-blur-md">
<div className="flex flex-col items-center pt-16 sm:pt-0"> <div className="flex flex-col items-center pt-16 sm:pt-0">
<img <img
src="/icon.png" src="/icon.png"
@ -84,10 +82,10 @@ export default function LoginPage() {
/> />
<div className="px-4 sm:mt-4 mt-8"> <div className="px-4 sm:mt-4 mt-8">
<h2 className="text-2xl font-bold text-gray-800 text-left w-full"> <h2 className="text-2xl font-bold text-gray-800 dark:text-gray-200 text-left w-full">
Sign In Sign In
</h2> </h2>
<h4 className="text-base mb-3 text-gray-400 text-left"> <h4 className="text-base mb-3 text-gray-400 dark:text-gray-500 text-left">
Enter your credentials to access home services and tools. Enter your credentials to access home services and tools.
</h4> </h4>
</div> </div>
@ -96,7 +94,7 @@ export default function LoginPage() {
<form onSubmit={handleSubmit(onSubmit)}> <form onSubmit={handleSubmit(onSubmit)}>
<div className="mb-4"> <div className="mb-4">
<div className="relative"> <div className="relative">
<Mail className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 w-4 h-4" /> <Mail className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 dark:text-gray-600 w-4 h-4" />
<Input <Input
id="email" id="email"
type="email" type="email"
@ -121,7 +119,7 @@ export default function LoginPage() {
<div className="mb-4"> <div className="mb-4">
<div className="relative"> <div className="relative">
<Lock className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 w-4 h-4" /> <Lock className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 dark:text-gray-600 w-4 h-4" />
<Input <Input
id="password" id="password"
type="password" type="password"
@ -147,7 +145,7 @@ export default function LoginPage() {
)} )}
{error.length > 0 && ( {error.length > 0 && (
<div className="border border-red-400 p-2 rounded bg-red-200 text-sm"> <div className="border border-red-400 p-2 rounded bg-red-200 dark:border-red-600 dark:bg-red-400 text-sm">
{error} {error}
</div> </div>
)} )}

View File

@ -4,7 +4,6 @@ import { Link } from "react-router-dom";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import overlay from "@/assets/overlay.jpg";
import { useCallback, useState } from "react"; import { useCallback, useState } from "react";
import { useForm, type SubmitHandler } from "react-hook-form"; import { useForm, type SubmitHandler } from "react-hook-form";
@ -75,11 +74,10 @@ export default function RegisterPage() {
return ( return (
<div <div
className="relative min-h-screen bg-cover bg-center bg-white" className={`relative min-h-screen bg-cover bg-center bg-white dark:bg-black bg-[url(/overlay.jpg)] dark:bg-[url(dark-overlay.jpg)]`}
style={{ backgroundImage: `url(${overlay})` }}
> >
<div className="relative z-10 flex items-center justify-center min-h-screen"> <div className="relative z-10 flex items-center justify-center min-h-screen">
<Card className="sm:w-96 sm:min-w-96 sm:max-w-96 sm:min-h-auto p-3 min-h-screen w-full min-w-full shadow-lg bg-white/90 backdrop-blur-md"> <Card className="sm:w-96 sm:min-w-96 sm:max-w-96 sm:min-h-auto p-3 min-h-screen w-full min-w-full shadow-lg bg-white/65 dark:bg-black/65 backdrop-blur-md">
<div className="flex flex-col items-center pt-16 sm:pt-0"> <div className="flex flex-col items-center pt-16 sm:pt-0">
<img <img
src="/icon.png" src="/icon.png"
@ -88,10 +86,10 @@ export default function RegisterPage() {
/> />
<div className="px-4 sm:mt-4 mt-8"> <div className="px-4 sm:mt-4 mt-8">
<h2 className="text-2xl font-bold text-gray-800 text-left w-full"> <h2 className="text-2xl font-bold text-gray-800 dark:text-gray-200 text-left w-full">
Sign Up Sign Up
</h2> </h2>
<h4 className="text-base mb-3 text-gray-400 text-left"> <h4 className="text-base mb-3 text-gray-400 dark:text-gray-600 text-left">
Fill up this form to start using homelab services and tools. Fill up this form to start using homelab services and tools.
</h4> </h4>
</div> </div>
@ -235,7 +233,7 @@ export default function RegisterPage() {
)} )}
{error.length > 0 && ( {error.length > 0 && (
<div className="border border-red-400 p-2 rounded bg-red-200 text-sm"> <div className="border border-red-400 p-2 rounded bg-red-200 dark:border-red-600 dark:bg-red-400 text-sm">
{error} {error}
</div> </div>
)} )}