Update frontend UI with improved layout and styling
- Enhanced homepage with modern design and better visual hierarchy - Improved login page with centered layout and better UX - Updated admin page with cleaner interface - Refined sidebar navigation and layout components - Updated Tailwind config and global styles - Fixed protected route component
This commit is contained in:
@@ -4,6 +4,9 @@
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet" />
|
||||
<title>Znakovni.hr - Hrvatski znakovni jezik</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -18,8 +18,8 @@ export function ProtectedRoute({ children, requireAdmin = false }: ProtectedRout
|
||||
return (
|
||||
<div className="flex h-screen items-center justify-center">
|
||||
<div className="text-center">
|
||||
<div className="h-8 w-8 animate-spin rounded-full border-4 border-blue-600 border-t-transparent mx-auto"></div>
|
||||
<p className="mt-4 text-slate-600">Loading...</p>
|
||||
<div className="h-8 w-8 animate-spin rounded-full border-4 border-indigo-600 border-t-transparent mx-auto"></div>
|
||||
<p className="mt-4 text-muted-foreground">Loading...</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -7,7 +7,7 @@ interface LayoutProps {
|
||||
|
||||
export function Layout({ children }: LayoutProps) {
|
||||
return (
|
||||
<div className="flex h-screen bg-slate-50">
|
||||
<div className="flex h-screen bg-indigo-50">
|
||||
<Sidebar />
|
||||
<main className="flex-1 overflow-y-auto">
|
||||
<div className="container mx-auto p-6 max-w-7xl">
|
||||
|
||||
@@ -44,10 +44,14 @@ export function Sidebar() {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex h-screen w-60 flex-col bg-slate-800 text-white">
|
||||
<div className="flex h-screen w-60 flex-col bg-white border-r border-border">
|
||||
{/* Logo */}
|
||||
<div className="flex h-16 items-center px-6 border-b border-slate-700">
|
||||
<h1 className="text-xl font-bold">Znakovni.hr</h1>
|
||||
<div className="flex h-16 items-center px-6 border-b border-border">
|
||||
<h1 className="text-xl font-bold">
|
||||
<span className="text-indigo-600">ZNAKOVNI</span>
|
||||
<span className="text-gray-400">.</span>
|
||||
<span className="text-orange-600">hr</span>
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
{/* Navigation */}
|
||||
@@ -63,8 +67,8 @@ export function Sidebar() {
|
||||
className={cn(
|
||||
'flex items-center gap-3 rounded-md px-3 py-2 text-sm font-medium transition-colors',
|
||||
isActive
|
||||
? 'bg-slate-700 text-white'
|
||||
: 'text-slate-300 hover:bg-slate-700 hover:text-white'
|
||||
? 'bg-primary text-primary-foreground'
|
||||
: 'text-muted-foreground hover:bg-secondary hover:text-foreground'
|
||||
)}
|
||||
>
|
||||
<item.icon className="h-5 w-5" />
|
||||
@@ -76,7 +80,7 @@ export function Sidebar() {
|
||||
|
||||
{/* Support Section */}
|
||||
<div className="pt-6">
|
||||
<h3 className="px-3 text-xs font-semibold uppercase tracking-wider text-slate-400 mb-2">
|
||||
<h3 className="px-3 text-xs font-semibold uppercase tracking-wider text-muted-foreground mb-2">
|
||||
Portal za podršku
|
||||
</h3>
|
||||
<div className="space-y-1">
|
||||
@@ -89,8 +93,8 @@ export function Sidebar() {
|
||||
className={cn(
|
||||
'flex items-center gap-3 rounded-md px-3 py-2 text-sm font-medium transition-colors',
|
||||
isActive
|
||||
? 'bg-slate-700 text-white'
|
||||
: 'text-slate-300 hover:bg-slate-700 hover:text-white'
|
||||
? 'bg-primary text-primary-foreground'
|
||||
: 'text-muted-foreground hover:bg-secondary hover:text-foreground'
|
||||
)}
|
||||
>
|
||||
<item.icon className="h-5 w-5" />
|
||||
@@ -109,8 +113,8 @@ export function Sidebar() {
|
||||
className={cn(
|
||||
'flex items-center gap-3 rounded-md px-3 py-2 text-sm font-medium transition-colors',
|
||||
location.pathname === '/admin'
|
||||
? 'bg-slate-700 text-white'
|
||||
: 'text-slate-300 hover:bg-slate-700 hover:text-white'
|
||||
? 'bg-primary text-primary-foreground'
|
||||
: 'text-muted-foreground hover:bg-secondary hover:text-foreground'
|
||||
)}
|
||||
>
|
||||
<Shield className="h-5 w-5" />
|
||||
@@ -121,16 +125,16 @@ export function Sidebar() {
|
||||
</nav>
|
||||
|
||||
{/* User Section */}
|
||||
<div className="border-t border-slate-700 p-4">
|
||||
<div className="border-t border-border p-4">
|
||||
{user ? (
|
||||
<div className="space-y-2">
|
||||
<div className="px-3 py-2">
|
||||
<p className="text-sm font-medium text-white">{user.displayName || user.email}</p>
|
||||
<p className="text-xs text-slate-400">{user.email}</p>
|
||||
<p className="text-sm font-medium text-foreground">{user.displayName || user.email}</p>
|
||||
<p className="text-xs text-muted-foreground">{user.email}</p>
|
||||
</div>
|
||||
<button
|
||||
onClick={handleLogout}
|
||||
className="flex w-full items-center gap-3 rounded-md px-3 py-2 text-sm font-medium text-slate-300 hover:bg-slate-700 hover:text-white transition-colors"
|
||||
className="flex w-full items-center gap-3 rounded-md px-3 py-2 text-sm font-medium text-muted-foreground hover:bg-secondary hover:text-foreground transition-colors"
|
||||
>
|
||||
<LogOut className="h-5 w-5" />
|
||||
Sign out
|
||||
@@ -139,7 +143,7 @@ export function Sidebar() {
|
||||
) : (
|
||||
<Link
|
||||
to="/login"
|
||||
className="flex items-center gap-3 rounded-md px-3 py-2 text-sm font-medium text-slate-300 hover:bg-slate-700 hover:text-white transition-colors"
|
||||
className="flex items-center gap-3 rounded-md px-3 py-2 text-sm font-medium text-muted-foreground hover:bg-secondary hover:text-foreground transition-colors"
|
||||
>
|
||||
Sign in
|
||||
</Link>
|
||||
|
||||
@@ -4,26 +4,38 @@
|
||||
|
||||
@layer base {
|
||||
:root {
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 222.2 84% 4.9%;
|
||||
/* Indigo-50 (#eef2ff) - Primary background */
|
||||
--background: 238 100% 97%;
|
||||
/* Slate-900 (#101828) - Primary text */
|
||||
--foreground: 222 47% 11%;
|
||||
--card: 0 0% 100%;
|
||||
--card-foreground: 222.2 84% 4.9%;
|
||||
--card-foreground: 222 47% 11%;
|
||||
--popover: 0 0% 100%;
|
||||
--popover-foreground: 222.2 84% 4.9%;
|
||||
--primary: 222.2 47.4% 11.2%;
|
||||
--primary-foreground: 210 40% 98%;
|
||||
--secondary: 210 40% 96.1%;
|
||||
--secondary-foreground: 222.2 47.4% 11.2%;
|
||||
--muted: 210 40% 96.1%;
|
||||
--muted-foreground: 215.4 16.3% 46.9%;
|
||||
--accent: 210 40% 96.1%;
|
||||
--accent-foreground: 222.2 47.4% 11.2%;
|
||||
--popover-foreground: 222 47% 11%;
|
||||
/* Indigo-600 (#4f39f6) - Primary accent color */
|
||||
--primary: 248 91% 60%;
|
||||
--primary-foreground: 0 0% 100%;
|
||||
/* Indigo-50 (#eef2ff) - Secondary background */
|
||||
--secondary: 238 100% 97%;
|
||||
--secondary-foreground: 248 91% 60%;
|
||||
/* Slate-100 (#f4f4f6) - Muted background */
|
||||
--muted: 240 5% 96%;
|
||||
/* Slate-600 (#4a5565) - Secondary text */
|
||||
--muted-foreground: 218 15% 35%;
|
||||
--accent: 238 100% 97%;
|
||||
--accent-foreground: 248 91% 60%;
|
||||
--destructive: 0 84.2% 60.2%;
|
||||
--destructive-foreground: 210 40% 98%;
|
||||
--border: 214.3 31.8% 91.4%;
|
||||
--input: 214.3 31.8% 91.4%;
|
||||
--ring: 222.2 84% 4.9%;
|
||||
--destructive-foreground: 0 0% 100%;
|
||||
/* Slate-300 (#d0d5e2) - Borders */
|
||||
--border: 225 20% 85%;
|
||||
--input: 225 20% 85%;
|
||||
--ring: 248 91% 60%;
|
||||
--radius: 0.5rem;
|
||||
|
||||
/* CEFR Level Colors */
|
||||
--cefr-a1-a2: 145 100% 33%; /* Green-600 (#00a63e) */
|
||||
--cefr-b1-b2: 32 100% 51%; /* Orange-500 (#ff8904) */
|
||||
--cefr-c1-c2: 14 100% 57%; /* Red-Orange (#ff5c33) */
|
||||
}
|
||||
|
||||
.dark {
|
||||
|
||||
@@ -111,8 +111,8 @@ export function Admin() {
|
||||
<Layout>
|
||||
<div className="flex items-center justify-center h-64">
|
||||
<div className="text-center">
|
||||
<div className="h-8 w-8 animate-spin rounded-full border-4 border-blue-600 border-t-transparent mx-auto"></div>
|
||||
<p className="mt-4 text-slate-600">Loading users...</p>
|
||||
<div className="h-8 w-8 animate-spin rounded-full border-4 border-primary border-t-transparent mx-auto"></div>
|
||||
<p className="mt-4 text-muted-foreground">Loading users...</p>
|
||||
</div>
|
||||
</div>
|
||||
</Layout>
|
||||
@@ -123,7 +123,7 @@ export function Admin() {
|
||||
<Layout>
|
||||
<div className="space-y-6">
|
||||
<div className="flex items-center justify-between">
|
||||
<h1 className="text-3xl font-bold text-slate-900">User Management</h1>
|
||||
<h1 className="text-3xl font-bold text-foreground">User Management</h1>
|
||||
<Button onClick={() => setShowCreateForm(true)} disabled={showCreateForm || !!editingUser}>
|
||||
<Plus className="h-4 w-4 mr-2" />
|
||||
Create User
|
||||
@@ -253,7 +253,7 @@ export function Admin() {
|
||||
<td className="px-6 py-4 whitespace-nowrap">
|
||||
<span className={`inline-flex px-2 py-1 text-xs font-semibold rounded-full ${
|
||||
user.role === 'ADMIN'
|
||||
? 'bg-purple-100 text-purple-800'
|
||||
? 'bg-indigo-100 text-indigo-800'
|
||||
: 'bg-gray-100 text-gray-800'
|
||||
}`}>
|
||||
{user.role}
|
||||
|
||||
@@ -9,28 +9,28 @@ function Home() {
|
||||
description: 'Browse and search Croatian sign language dictionary',
|
||||
icon: BookOpen,
|
||||
href: '/dictionary',
|
||||
color: 'bg-blue-500',
|
||||
color: 'bg-indigo-600',
|
||||
},
|
||||
{
|
||||
name: 'Znakopis',
|
||||
description: 'Build sentences using sign language',
|
||||
icon: FileText,
|
||||
href: '/znakopis',
|
||||
color: 'bg-green-500',
|
||||
color: 'bg-gray-400',
|
||||
},
|
||||
{
|
||||
name: 'Video rečenica',
|
||||
description: 'Watch and learn from video sentences',
|
||||
icon: Video,
|
||||
href: '/video-sentence',
|
||||
color: 'bg-purple-500',
|
||||
color: 'bg-orange-600',
|
||||
},
|
||||
{
|
||||
name: 'Oblak',
|
||||
description: 'Save and manage your documents in the cloud',
|
||||
icon: Cloud,
|
||||
href: '/cloud',
|
||||
color: 'bg-orange-500',
|
||||
color: 'bg-indigo-600',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -38,10 +38,10 @@ function Home() {
|
||||
<Layout>
|
||||
<div className="space-y-8">
|
||||
<div className="text-center">
|
||||
<h1 className="text-4xl font-bold text-slate-900 mb-4">
|
||||
Dobrodošli na Znakovni.hr
|
||||
<h1 className="text-4xl font-bold text-foreground mb-4">
|
||||
Tvoj put u svijet znakovnog jezika
|
||||
</h1>
|
||||
<p className="text-lg text-slate-600">
|
||||
<p className="text-lg text-muted-foreground">
|
||||
Hrvatski znakovni jezik - platforma za učenje i komunikaciju
|
||||
</p>
|
||||
</div>
|
||||
@@ -58,10 +58,10 @@ function Home() {
|
||||
<feature.icon className="h-8 w-8 text-white" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-xl font-semibold text-slate-900">
|
||||
<h3 className="text-xl font-semibold text-foreground">
|
||||
{feature.name}
|
||||
</h3>
|
||||
<p className="text-slate-600 mt-1">{feature.description}</p>
|
||||
<p className="text-muted-foreground mt-1">{feature.description}</p>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
|
||||
@@ -25,12 +25,16 @@ export function Login() {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex min-h-screen items-center justify-center bg-slate-50">
|
||||
<div className="w-full max-w-md space-y-8 rounded-lg bg-white p-8 shadow-lg">
|
||||
<div className="flex min-h-screen items-center justify-center bg-background">
|
||||
<div className="w-full max-w-md space-y-8 rounded-lg bg-card p-8 shadow-lg">
|
||||
{/* Logo */}
|
||||
<div className="text-center">
|
||||
<h1 className="text-3xl font-bold text-slate-900">Znakovni.hr</h1>
|
||||
<p className="mt-2 text-sm text-slate-600">
|
||||
<h1 className="text-3xl font-bold">
|
||||
<span className="text-indigo-600">ZNAKOVNI</span>
|
||||
<span className="text-gray-400">.</span>
|
||||
<span className="text-orange-600">hr</span>
|
||||
</h1>
|
||||
<p className="mt-2 text-sm text-muted-foreground">
|
||||
Hrvatski znakovni jezik
|
||||
</p>
|
||||
</div>
|
||||
@@ -83,7 +87,7 @@ export function Login() {
|
||||
</form>
|
||||
|
||||
{/* Demo Credentials */}
|
||||
<div className="mt-4 rounded-md bg-blue-50 p-4 text-sm text-blue-800">
|
||||
<div className="mt-4 rounded-md bg-indigo-50 p-4 text-sm text-indigo-800">
|
||||
<p className="font-semibold">Demo Credentials:</p>
|
||||
<p className="mt-1">Admin: admin@znakovni.hr / admin123</p>
|
||||
<p>User: demo@znakovni.hr / demo123</p>
|
||||
|
||||
@@ -4,6 +4,9 @@ export default {
|
||||
content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
|
||||
theme: {
|
||||
extend: {
|
||||
fontFamily: {
|
||||
sans: ['Inter', 'system-ui', 'sans-serif'],
|
||||
},
|
||||
colors: {
|
||||
border: 'hsl(var(--border))',
|
||||
input: 'hsl(var(--input))',
|
||||
@@ -38,6 +41,11 @@ export default {
|
||||
DEFAULT: 'hsl(var(--card))',
|
||||
foreground: 'hsl(var(--card-foreground))',
|
||||
},
|
||||
cefr: {
|
||||
'a1-a2': 'hsl(var(--cefr-a1-a2))',
|
||||
'b1-b2': 'hsl(var(--cefr-b1-b2))',
|
||||
'c1-c2': 'hsl(var(--cefr-c1-c2))',
|
||||
},
|
||||
},
|
||||
borderRadius: {
|
||||
lg: 'var(--radius)',
|
||||
|
||||
Reference in New Issue
Block a user