- Timestamp:
- 02/13/26 19:32:02 (7 months ago)
- Branches:
- master
- Children:
- d7deae5
- Parents:
- 50f2fb4
- Location:
- src
- Files:
-
- 2 added
- 16 edited
-
app/globals.css (modified) (2 diffs)
-
app/layout.tsx (modified) (2 diffs)
-
app/page.tsx (modified) (11 diffs)
-
app/professor/profile/page.tsx (modified) (4 diffs)
-
app/professor/students/page.tsx (modified) (8 diffs)
-
app/students/applications/page.tsx (modified) (17 diffs)
-
app/students/documents/page.tsx (modified) (27 diffs)
-
app/students/layout.tsx (modified) (1 diff)
-
app/students/profile/page.tsx (modified) (4 diffs)
-
app/students/semesters/page.tsx (modified) (18 diffs)
-
app/students/subjects/page.tsx (modified) (17 diffs)
-
components/LanguageSwitcher.tsx (modified) (2 diffs)
-
components/exams.tsx (modified) (9 diffs)
-
components/header.tsx (modified) (3 diffs)
-
components/navbar.tsx (modified) (4 diffs)
-
components/professor-navbar.tsx (modified) (4 diffs)
-
components/theme-provider.tsx (added)
-
components/theme-toggle.tsx (added)
Legend:
- Unmodified
- Added
- Removed
-
src/app/globals.css
r50f2fb4 rba52069 80 80 81 81 .dark { 82 --background: oklch(0.1 45 00);83 --foreground: oklch(0.9 85 00);84 --card: oklch(0. 205 00);85 --card-foreground: oklch(0.9 85 00);86 --popover: oklch(0. 205 00);87 --popover-foreground: oklch(0.9 85 00);88 --primary: oklch(0.922 0 0);89 --primary-foreground: oklch(0. 2050 0);90 --secondary: oklch(0.2 69 00);91 --secondary-foreground: oklch(0.9 85 00);92 --muted: oklch(0.2 69 00);93 --muted-foreground: oklch(0. 708 00);94 --accent: oklch(0.2 69 00);95 --accent-foreground: oklch(0.9 85 00);96 --destructive: oklch(0. 704 0.191 22.216);97 --border: oklch( 1 0 0 / 10%);98 --input: oklch( 1 0 0 / 15%);99 --ring: oklch(0.5 56 00);100 --chart-1: oklch(0. 488 0.243 264.376);101 --chart-2: oklch(0.6 96 0.17 162.48);102 --chart-3: oklch(0.7 69 0.188 70.08);103 --chart-4: oklch(0.6 27 0.265 303.9);104 --chart-5: oklch(0.6 45 0.246 16.439);105 --sidebar: oklch(0. 205 00);106 --sidebar-foreground: oklch(0.9 85 00);107 --sidebar-primary: oklch(0. 488 0.243 264.376);108 --sidebar-primary-foreground: oklch(0.98 50 0);109 --sidebar-accent: oklch(0.2 69 00);110 --sidebar-accent-foreground: oklch(0.9 85 00);111 --sidebar-border: oklch( 1 0 0 / 10%);112 --sidebar-ring: oklch(0.5 56 00);82 --background: oklch(0.15 0.01 240); 83 --foreground: oklch(0.95 0.01 240); 84 --card: oklch(0.18 0.01 240); 85 --card-foreground: oklch(0.95 0.01 240); 86 --popover: oklch(0.18 0.01 240); 87 --popover-foreground: oklch(0.95 0.01 240); 88 --primary: #3b82f6; 89 --primary-foreground: oklch(0.98 0 0); 90 --secondary: oklch(0.25 0.01 240); 91 --secondary-foreground: oklch(0.95 0.01 240); 92 --muted: oklch(0.25 0.01 240); 93 --muted-foreground: oklch(0.65 0.01 240); 94 --accent: oklch(0.25 0.01 240); 95 --accent-foreground: oklch(0.95 0.01 240); 96 --destructive: oklch(0.6 0.22 25); 97 --border: oklch(0.3 0.01 240); 98 --input: oklch(0.25 0.01 240); 99 --ring: oklch(0.5 0.15 240); 100 --chart-1: oklch(0.6 0.2 270); 101 --chart-2: oklch(0.65 0.18 180); 102 --chart-3: oklch(0.7 0.19 90); 103 --chart-4: oklch(0.6 0.24 310); 104 --chart-5: oklch(0.65 0.22 30); 105 --sidebar: oklch(0.18 0.01 240); 106 --sidebar-foreground: oklch(0.95 0.01 240); 107 --sidebar-primary: oklch(0.5 0.2 260); 108 --sidebar-primary-foreground: oklch(0.98 0 0); 109 --sidebar-accent: oklch(0.25 0.01 240); 110 --sidebar-accent-foreground: oklch(0.95 0.01 240); 111 --sidebar-border: oklch(0.3 0.01 240); 112 --sidebar-ring: oklch(0.5 0.15 240); 113 113 } 114 114 … … 118 118 } 119 119 body { 120 @apply text-foreground; 121 background-color: #F4FAFF; 120 @apply text-foreground bg-background; 122 121 } 123 122 } -
src/app/layout.tsx
r50f2fb4 rba52069 6 6 import { I18nextProvider } from 'react-i18next'; 7 7 import i18n from '../i18n'; 8 import { ThemeProvider } from '../components/theme-provider'; 9 import { ThemeToggle } from '../components/theme-toggle'; 8 10 9 11 config.autoAddCss = false; … … 25 27 }>) { 26 28 return ( 27 <html lang="en" >29 <html lang="en" suppressHydrationWarning> 28 30 <body className={`${geistSans.variable} ${geistMono.variable} antialiased`}> 29 <I18nextProvider i18n={i18n}> 30 <div className="mx-auto max-w-6xl px-4">{children}</div> 31 </I18nextProvider> 31 <ThemeProvider attribute="class" defaultTheme="system" enableSystem> 32 <I18nextProvider i18n={i18n}> 33 <div className="fixed top-4 right-4 z-50"> 34 <ThemeToggle /> 35 </div> 36 <div className="mx-auto max-w-6xl px-4">{children}</div> 37 </I18nextProvider> 38 </ThemeProvider> 32 39 </body> 33 40 </html> -
src/app/page.tsx
r50f2fb4 rba52069 56 56 {/* Sticky Notes */} 57 57 <div className="w-full flex flex-col gap-4"> 58 <div className="bg-yellow- 100 border border-yellow-200 rounded-xl shadow-sm p-5">59 <div className="text-sm font-bold text- gray-900mb-2">{t('login_student_title')}</div>60 <div className="text-xs text- gray-800whitespace-pre-wrap font-mono">58 <div className="bg-yellow-500/10 border border-yellow-500/20 rounded-xl shadow-sm p-5"> 59 <div className="text-sm font-bold text-card-foreground mb-2">{t('login_student_title')}</div> 60 <div className="text-xs text-card-foreground whitespace-pre-wrap font-mono"> 61 61 {t('login_student_example')} 62 62 </div> 63 <div className="mt-3 text-xs text- gray-700">63 <div className="mt-3 text-xs text-muted-foreground"> 64 64 {t('login_note_slow')} 65 65 </div> 66 66 </div> 67 67 68 <div className="bg-yellow- 100 border border-yellow-200 rounded-xl shadow-sm p-5">69 <div className="text-sm font-bold text- gray-900mb-2">{t('login_professor_title')}</div>70 <div className="text-xs text- gray-800whitespace-pre-wrap font-mono">68 <div className="bg-yellow-500/10 border border-yellow-500/20 rounded-xl shadow-sm p-5"> 69 <div className="text-sm font-bold text-card-foreground mb-2">{t('login_professor_title')}</div> 70 <div className="text-xs text-card-foreground whitespace-pre-wrap font-mono"> 71 71 {t('login_professor_example')} 72 72 </div> … … 77 77 <div className="w-full max-w-md lg:max-w-none lg:w-[28rem] mx-auto"> 78 78 {/* Login Card */} 79 <div className="bg- white rounded-2xl shadow-xl border border-gray-100overflow-hidden">79 <div className="bg-card rounded-2xl shadow-xl border border-border overflow-hidden"> 80 80 {/* Header */} 81 81 <div className="bg-primary text-white px-8 py-6 text-center"> 82 82 <div className="mb-4"> 83 <div className="inline-flex items-center justify-center w-16 h-16 bg-white bg-opacity-20 rounded-full">84 <FontAwesomeIcon icon={faUser} className="text-2xl text- primary" />83 <div className="inline-flex items-center justify-center w-16 h-16 bg-white rounded-full shadow-lg"> 84 <FontAwesomeIcon icon={faUser} className="text-2xl text-[#0272D1]" /> 85 85 </div> 86 86 </div> … … 100 100 {/* Email Field */} 101 101 <div> 102 <label htmlFor="email" className="block text-sm font-medium text- gray-700mb-2">102 <label htmlFor="email" className="block text-sm font-medium text-muted-foreground mb-2"> 103 103 {t('login_email_label')} 104 104 </label> 105 105 <div className="relative"> 106 106 <div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none"> 107 <FontAwesomeIcon icon={faUser} className="h-4 w-4 text- gray-400" />107 <FontAwesomeIcon icon={faUser} className="h-4 w-4 text-muted-foreground" /> 108 108 </div> 109 109 <input … … 114 114 value={formData.email} 115 115 onChange={handleInputChange} 116 className="w-full pl-10 pr-4 py-3 border border- gray-300rounded-lg focus:outline-none focus:ring-2 focus:ring-primary focus:border-primary transition-colors"116 className="w-full pl-10 pr-4 py-3 border border-input rounded-lg focus:outline-none focus:ring-2 focus:ring-primary focus:border-primary transition-colors" 117 117 placeholder={t('login_email_placeholder')} 118 118 /> … … 122 122 {/* Password Field */} 123 123 <div> 124 <label htmlFor="password" className="block text-sm font-medium text- gray-700mb-2">124 <label htmlFor="password" className="block text-sm font-medium text-muted-foreground mb-2"> 125 125 {t('login_password_label')} 126 126 </label> 127 127 <div className="relative"> 128 128 <div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none"> 129 <FontAwesomeIcon icon={faLock} className="h-4 w-4 text- gray-400" />129 <FontAwesomeIcon icon={faLock} className="h-4 w-4 text-muted-foreground" /> 130 130 </div> 131 131 <input … … 136 136 value={formData.password} 137 137 onChange={handleInputChange} 138 className="w-full pl-10 pr-12 py-3 border border- gray-300rounded-lg focus:outline-none focus:ring-2 focus:ring-primary focus:border-primary transition-colors"138 className="w-full pl-10 pr-12 py-3 border border-input rounded-lg focus:outline-none focus:ring-2 focus:ring-primary focus:border-primary transition-colors" 139 139 placeholder={t('login_password_placeholder')} 140 140 /> … … 142 142 type="button" 143 143 onClick={() => setShowPassword(!showPassword)} 144 className="absolute inset-y-0 right-0 pr-3 flex items-center text- gray-400 hover:text-gray-600transition-colors"144 className="absolute inset-y-0 right-0 pr-3 flex items-center text-muted-foreground hover:text-foreground transition-colors" 145 145 > 146 146 <FontAwesomeIcon … … 159 159 name="remember" 160 160 type="checkbox" 161 className="h-4 w-4 text-primary focus:ring-primary border- gray-300rounded"161 className="h-4 w-4 text-primary focus:ring-primary border-input rounded" 162 162 /> 163 <label htmlFor="remember" className="ml-2 block text-sm text- gray-700">163 <label htmlFor="remember" className="ml-2 block text-sm text-muted-foreground"> 164 164 {t('login_remember_me')} 165 165 </label> … … 174 174 175 175 {errorMessage && ( 176 <div className="rounded-lg border border- red-200 bg-red-50 px-4 py-3 text-sm text-red-700">176 <div className="rounded-lg border border-destructive/20 bg-destructive/10 px-4 py-3 text-sm text-destructive"> 177 177 {t(errorMessage) || errorMessage} 178 178 </div> … … 192 192 193 193 {/* Footer */} 194 <div className="bg- gray-50 px-8 py-4 border-t border-gray-100">195 <p className="text-center text-sm text- gray-600">194 <div className="bg-accent px-8 py-4 border-t border-border"> 195 <p className="text-center text-sm text-muted-foreground"> 196 196 {t('login_no_account')}{' '} 197 197 <button className="text-primary hover:text-blue-700 font-medium transition-colors"> … … 204 204 {/* Additional Info */} 205 205 <div className="mt-6 text-center"> 206 <div className="inline-flex items-center gap-2 px-4 py-2 bg- whitebg-opacity-80 rounded-lg shadow-sm">206 <div className="inline-flex items-center gap-2 px-4 py-2 bg-card bg-opacity-80 rounded-lg shadow-sm"> 207 207 <FontAwesomeIcon icon={faGraduationCap} className="text-primary" /> 208 <span className="text-sm text- gray-600">208 <span className="text-sm text-muted-foreground"> 209 209 {t('login_footer')} 210 210 </span> -
src/app/professor/profile/page.tsx
r50f2fb4 rba52069 98 98 const { t } = useTranslation(); 99 99 return ( 100 <div className="flex justify-between items-center py-3 border-b border- gray-100last:border-b-0">101 <div className="flex items-center gap-2 text- gray-600font-medium">100 <div className="flex justify-between items-center py-3 border-b border-border last:border-b-0"> 101 <div className="flex items-center gap-2 text-muted-foreground font-medium"> 102 102 {icon && <FontAwesomeIcon icon={icon} className="w-4 h-4" />} 103 103 <span>{t(label)}:</span> 104 104 </div> 105 <div className="text- gray-900font-semibold text-right max-w-xs break-words">105 <div className="text-card-foreground font-semibold text-right max-w-xs break-words"> 106 106 {value || t('n_a')} 107 107 </div> … … 119 119 const { t } = useTranslation(); 120 120 return ( 121 <div className="bg- white rounded-xl shadow-sm border border-gray-100overflow-hidden">121 <div className="bg-card rounded-xl shadow-sm border border-border overflow-hidden"> 122 122 <div className="bg-primary text-white px-6 py-4"> 123 123 <div className="flex items-center gap-3"> … … 185 185 return ( 186 186 <div className="min-h-screen pb-8"> 187 <div className="bg- white rounded-xl shadow-sm border border-gray-100p-6">{t('loading')}</div>187 <div className="bg-card rounded-xl shadow-sm border border-border p-6">{t('loading')}</div> 188 188 </div> 189 189 ); … … 208 208 <div className="flex items-center gap-6"> 209 209 <div className="relative"> 210 <div className="w-20 h-20 bg-white bg-opacity-20 rounded-full flex items-center justify-center border-2 border-white border-opacity-30">211 <FontAwesomeIcon icon={faUser} className="text-3xl text- primary" />210 <div className="w-20 h-20 bg-white rounded-full flex items-center justify-center border-2 border-white shadow-lg"> 211 <FontAwesomeIcon icon={faUser} className="text-3xl text-[#0272D1]" /> 212 212 </div> 213 213 <div className="absolute -bottom-1 -right-1 w-6 h-6 bg-green-500 rounded-full border-2 border-white"></div> -
src/app/professor/students/page.tsx
r50f2fb4 rba52069 129 129 130 130 return ( 131 <div className="bg- white rounded-xl shadow-sm border border-gray-200p-6">131 <div className="bg-card rounded-xl shadow-sm border border-border p-6"> 132 132 <div className="flex flex-col gap-4 md:flex-row md:items-end md:justify-between"> 133 133 134 134 <div> 135 <h1 className="text-2xl font-semibold text- gray-900">{t('prof_students_title')}</h1>136 <p className="text- gray-700mt-1">135 <h1 className="text-2xl font-semibold text-card-foreground">{t('prof_students_title')}</h1> 136 <p className="text-muted-foreground mt-1"> 137 137 {t('prof_students_data_note')} <span className="font-mono">/api/prof/students</span> (demo store). 138 138 </p> … … 141 141 <div className="flex flex-col sm:flex-row gap-3"> 142 142 <div className="flex flex-col"> 143 <label className="text-sm text- gray-700">{t('filter_by_subject')}</label>143 <label className="text-sm text-muted-foreground">{t('filter_by_subject')}</label> 144 144 <select 145 className="border border- gray-300rounded-lg px-3 py-2"145 className="border border-border rounded-lg px-3 py-2" 146 146 value={subjectFilter} 147 147 onChange={(e) => setSubjectFilter(e.target.value)} … … 159 159 160 160 <div className="flex flex-col"> 161 <label className="text-sm text- gray-700">{t('find_student_by_id')}</label>161 <label className="text-sm text-muted-foreground">{t('find_student_by_id')}</label> 162 162 <input 163 className="border border- gray-300rounded-lg px-3 py-2"163 className="border border-border rounded-lg px-3 py-2" 164 164 placeholder={t('student_id_placeholder')} 165 165 value={studentIdQuery} … … 177 177 178 178 <div className="mt-6 overflow-x-auto"> 179 <table className="min-w-full border border- gray-200rounded-lg overflow-hidden">180 <thead className="bg- gray-50">179 <table className="min-w-full border border-border rounded-lg overflow-hidden"> 180 <thead className="bg-accent"> 181 181 <tr> 182 <th className="text-left text-sm font-semibold text- gray-700px-4 py-3 border-b">{t('student')}</th>183 <th className="text-left text-sm font-semibold text- gray-700px-4 py-3 border-b">{t('id')}</th>184 <th className="text-left text-sm font-semibold text- gray-700px-4 py-3 border-b">{t('subject')}</th>185 <th className="text-left text-sm font-semibold text- gray-700px-4 py-3 border-b">{t('grade')}</th>186 <th className="text-left text-sm font-semibold text- gray-700px-4 py-3 border-b">{t('actions')}</th>182 <th className="text-left text-sm font-semibold text-muted-foreground px-4 py-3 border-b">{t('student')}</th> 183 <th className="text-left text-sm font-semibold text-muted-foreground px-4 py-3 border-b">{t('id')}</th> 184 <th className="text-left text-sm font-semibold text-muted-foreground px-4 py-3 border-b">{t('subject')}</th> 185 <th className="text-left text-sm font-semibold text-muted-foreground px-4 py-3 border-b">{t('grade')}</th> 186 <th className="text-left text-sm font-semibold text-muted-foreground px-4 py-3 border-b">{t('actions')}</th> 187 187 </tr> 188 188 </thead> … … 190 190 {loading ? ( 191 191 <tr> 192 <td className="px-4 py-4 text- gray-700" colSpan={5}>192 <td className="px-4 py-4 text-muted-foreground" colSpan={5}> 193 193 {t('loading')} 194 194 </td> … … 196 196 ) : filteredRows.length === 0 ? ( 197 197 <tr> 198 <td className="px-4 py-4 text- gray-700" colSpan={5}>198 <td className="px-4 py-4 text-muted-foreground" colSpan={5}> 199 199 {t('no_students_found')} 200 200 </td> … … 207 207 208 208 return ( 209 <tr key={key} className="hover:bg- gray-50">210 <td className="px-4 py-3 border-b text- gray-900">{r.studentName}</td>211 <td className="px-4 py-3 border-b text- gray-900">{r.studentIdStr}</td>212 <td className="px-4 py-3 border-b text- gray-900">{r.subjectName}</td>209 <tr key={key} className="hover:bg-accent"> 210 <td className="px-4 py-3 border-b text-card-foreground">{r.studentName}</td> 211 <td className="px-4 py-3 border-b text-card-foreground">{r.studentIdStr}</td> 212 <td className="px-4 py-3 border-b text-card-foreground">{r.subjectName}</td> 213 213 <td className="px-4 py-3 border-b"> 214 214 <div className="flex items-center gap-3"> 215 215 <select 216 className="border border- gray-300rounded-lg px-3 py-2"216 className="border border-border rounded-lg px-3 py-2" 217 217 value={selected} 218 218 onChange={(e) => … … 229 229 ))} 230 230 </select> 231 <span className="text-sm text- gray-600">231 <span className="text-sm text-muted-foreground"> 232 232 {t('current')}: {r.grade > 0 ? r.grade : t('none')} 233 233 </span> -
src/app/students/applications/page.tsx
r50f2fb4 rba52069 23 23 24 24 const TableCell = ({ children, className = "" }: TableCellProps) => ( 25 <td className={`px-4 py-3 text-sm border-b border- gray-200${className}`}>25 <td className={`px-4 py-3 text-sm border-b border-border ${className}`}> 26 26 {children} 27 27 </td> … … 78 78 <div className="bg-primary text-white rounded-xl p-8 mb-8"> 79 79 <div className="flex items-center gap-4"> 80 <div className="bg-white bg-opacity-20rounded-full p-4">81 <FontAwesomeIcon icon={faPenToSquare} className="text-3xl text- primary" />80 <div className="bg-white rounded-full p-4"> 81 <FontAwesomeIcon icon={faPenToSquare} className="text-3xl text-[#0272D1]" /> 82 82 </div> 83 83 <div> … … 91 91 92 92 {/* Session Selection */} 93 <div className="bg- white rounded-xl p-6 shadow-sm border border-gray-100mb-8">93 <div className="bg-card rounded-xl p-6 shadow-sm border border-border mb-8"> 94 94 <div className="flex items-center justify-between"> 95 <h2 className="text-lg font-semibold text- gray-900flex items-center gap-2">95 <h2 className="text-lg font-semibold text-card-foreground flex items-center gap-2"> 96 96 <FontAwesomeIcon icon={faCalendarAlt} className="text-primary" /> 97 97 {t('select_exam_session', 'Избери испитна сесија:')} … … 101 101 <button 102 102 onClick={() => setIsDropdownOpen(!isDropdownOpen)} 103 className="bg- white border border-gray-300rounded-lg px-4 py-2 text-left focus:outline-none focus:ring-2 focus:ring-primary focus:border-primary min-w-80"103 className="bg-card border border-border rounded-lg px-4 py-2 text-left focus:outline-none focus:ring-2 focus:ring-primary focus:border-primary min-w-80" 104 104 > 105 105 <div className="flex items-center justify-between"> … … 109 109 <FontAwesomeIcon 110 110 icon={faChevronDown} 111 className={`w-4 h-4 text- gray-400transition-transform ml-4 ${isDropdownOpen ? 'rotate-180' : ''}`}111 className={`w-4 h-4 text-muted-foreground transition-transform ml-4 ${isDropdownOpen ? 'rotate-180' : ''}`} 112 112 /> 113 113 </div> … … 115 115 116 116 {isDropdownOpen && ( 117 <div className="absolute z-10 right-0 mt-1 w-80 bg- white border border-gray-200rounded-lg shadow-lg">117 <div className="absolute z-10 right-0 mt-1 w-80 bg-card border border-border rounded-lg shadow-lg"> 118 118 {applicationsData.examSessions.map((session) => ( 119 119 <button … … 123 123 setIsDropdownOpen(false); 124 124 }} 125 className="w-full px-4 py-3 text-left text-sm hover:bg- gray-50 focus:outline-none focus:bg-gray-50first:rounded-t-lg last:rounded-b-lg"125 className="w-full px-4 py-3 text-left text-sm hover:bg-accent focus:outline-none focus:bg-accent first:rounded-t-lg last:rounded-b-lg" 126 126 > 127 <div className="font-medium text- gray-900">{t(session.id, session.name)}</div>128 <div className="text-xs text- gray-500">{session.year} - {t(session.semester, session.semester)} - {t(session.session, session.session)}</div>127 <div className="font-medium text-card-foreground">{t(session.id, session.name)}</div> 128 <div className="text-xs text-muted-foreground">{session.year} - {t(session.semester, session.semester)} - {t(session.session, session.session)}</div> 129 129 </button> 130 130 ))} … … 136 136 137 137 {/* Applications Section */} 138 <div className="bg- white rounded-xl shadow-sm border border-gray-100overflow-hidden">138 <div className="bg-card rounded-xl shadow-sm border border-border overflow-hidden"> 139 139 <div className="bg-primary text-white px-6 py-4"> 140 140 <h2 className="text-xl font-bold">{t('registered_exams', 'Пријавени испити')}</h2> … … 143 143 <div className="overflow-x-auto"> 144 144 <table className="w-full"> 145 <thead className="bg- gray-50">145 <thead className="bg-accent"> 146 146 <tr> 147 <th className="px-4 py-4 text-left text-xs font-medium text- gray-500uppercase tracking-wider">#</th>148 <th className="px-4 py-4 text-left text-xs font-medium text- gray-500uppercase tracking-wider">{t('serial_number', 'Сериски број')}</th>149 <th className="px-4 py-4 text-left text-xs font-medium text- gray-500uppercase tracking-wider">{t('code', 'Код')}</th>150 <th className="px-4 py-4 text-left text-xs font-medium text- gray-500uppercase tracking-wider">{t('subject', 'Предмет')}</th>151 <th className="px-4 py-4 text-center text-xs font-medium text- gray-500uppercase tracking-wider">{t('completed', 'Завршена')}</th>152 <th className="px-4 py-4 text-center text-xs font-medium text- gray-500uppercase tracking-wider">{t('fee', 'Таксени')}</th>153 <th className="px-4 py-4 text-left text-xs font-medium text- gray-500uppercase tracking-wider">{t('date', 'Датум')}</th>154 <th className="px-4 py-4 text-left text-xs font-medium text- gray-500uppercase tracking-wider">{t('instructor', 'Наставник')}</th>155 <th className="px-4 py-4 text-center text-xs font-medium text- gray-500uppercase tracking-wider">{t('decade', 'Декада')}</th>147 <th className="px-4 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">#</th> 148 <th className="px-4 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('serial_number', 'Сериски број')}</th> 149 <th className="px-4 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('code', 'Код')}</th> 150 <th className="px-4 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('subject', 'Предмет')}</th> 151 <th className="px-4 py-4 text-center text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('completed', 'Завршена')}</th> 152 <th className="px-4 py-4 text-center text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('fee', 'Таксени')}</th> 153 <th className="px-4 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('date', 'Датум')}</th> 154 <th className="px-4 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('instructor', 'Наставник')}</th> 155 <th className="px-4 py-4 text-center text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('decade', 'Декада')}</th> 156 156 </tr> 157 157 </thead> 158 <tbody className="divide-y divide- gray-100">158 <tbody className="divide-y divide-border"> 159 159 {applications.map((application) => ( 160 <tr key={application.id} className="hover:bg- gray-50transition-colors">161 <TableCell className="font-medium text- gray-900">{application.id}</TableCell>160 <tr key={application.id} className="hover:bg-accent transition-colors"> 161 <TableCell className="font-medium text-card-foreground">{application.id}</TableCell> 162 162 <TableCell> 163 163 <span className="font-mono text-sm text-primary font-medium hover:underline cursor-pointer"> … … 166 166 </TableCell> 167 167 <TableCell className="font-mono text-sm font-medium">{application.code}</TableCell> 168 <TableCell className="font-medium text- gray-900max-w-xs">168 <TableCell className="font-medium text-card-foreground max-w-xs"> 169 169 <div className="flex items-center gap-2"> 170 170 <FontAwesomeIcon icon={faFileText} className="w-4 h-4 text-primary" /> … … 178 178 <FeeBadge fee={application.fee} /> 179 179 </TableCell> 180 <TableCell className="text- gray-600font-medium">{application.date}</TableCell>180 <TableCell className="text-muted-foreground font-medium">{application.date}</TableCell> 181 181 <TableCell> 182 182 <div className="flex items-center gap-2"> 183 <FontAwesomeIcon icon={faUser} className="w-4 h-4 text- gray-400" />184 <span className="font-medium text- gray-900">{t(application.instructor, application.instructor)}</span>183 <FontAwesomeIcon icon={faUser} className="w-4 h-4 text-muted-foreground" /> 184 <span className="font-medium text-card-foreground">{t(application.instructor, application.instructor)}</span> 185 185 </div> 186 186 </TableCell> … … 208 208 {/* Statistics Cards */} 209 209 <div className="grid grid-cols-1 md:grid-cols-3 gap-6 mt-8"> 210 <div className="bg- white rounded-xl p-6 shadow-sm border border-gray-100">210 <div className="bg-card rounded-xl p-6 shadow-sm border border-border"> 211 211 <div className="flex items-center gap-4"> 212 212 <div className="bg-blue-100 text-blue-600 rounded-full p-3"> … … 214 214 </div> 215 215 <div> 216 <h3 className="text-lg font-bold text- gray-900">{t('registered_exams', 'Пријавени испити')}</h3>216 <h3 className="text-lg font-bold text-card-foreground">{t('registered_exams', 'Пријавени испити')}</h3> 217 217 <p className="text-2xl font-bold text-blue-600"> 218 218 {applications.length} … … 222 222 </div> 223 223 224 <div className="bg- white rounded-xl p-6 shadow-sm border border-gray-100">224 <div className="bg-card rounded-xl p-6 shadow-sm border border-border"> 225 225 <div className="flex items-center gap-4"> 226 226 <div className="bg-green-100 text-green-600 rounded-full p-3"> … … 228 228 </div> 229 229 <div> 230 <h3 className="text-lg font-bold text- gray-900">{t('completed', 'Завршени')}</h3>230 <h3 className="text-lg font-bold text-card-foreground">{t('completed', 'Завршени')}</h3> 231 231 <p className="text-2xl font-bold text-green-600"> 232 232 {applications.filter(app => app.completed === t('yes', 'Да')).length} … … 236 236 </div> 237 237 238 <div className="bg- white rounded-xl p-6 shadow-sm border border-gray-100">238 <div className="bg-card rounded-xl p-6 shadow-sm border border-border"> 239 239 <div className="flex items-center gap-4"> 240 240 <div className="bg-yellow-100 text-yellow-600 rounded-full p-3"> … … 242 242 </div> 243 243 <div> 244 <h3 className="text-lg font-bold text- gray-900">{t('total_fee', 'Вкупна такса')}</h3>244 <h3 className="text-lg font-bold text-card-foreground">{t('total_fee', 'Вкупна такса')}</h3> 245 245 <p className="text-2xl font-bold text-yellow-600"> 246 246 {applications.reduce((sum, app) => sum + parseFloat(app.fee.replace(',', '.')), 0).toFixed(2)} -
src/app/students/documents/page.tsx
r50f2fb4 rba52069 23 23 24 24 const TableCell = ({ children, className = "" }: TableCellProps) => ( 25 <td className={`px-4 py-3 text-sm border-b border- gray-200${className}`}>25 <td className={`px-4 py-3 text-sm border-b border-border ${className}`}> 26 26 {children} 27 27 </td> … … 38 38 } 39 39 return ( 40 <span className="inline-flex items-center justify-center w-8 h-8 bg- gray-100 text-gray-600rounded-full">40 <span className="inline-flex items-center justify-center w-8 h-8 bg-accent text-muted-foreground rounded-full"> 41 41 <FontAwesomeIcon icon={faFileText} className="w-4 h-4" /> 42 42 </span> … … 73 73 <div className="bg-primary text-white rounded-xl p-8 mb-8"> 74 74 <div className="flex items-center gap-4"> 75 <div className="bg-white bg-opacity-20rounded-full p-4">76 <FontAwesomeIcon icon={faFilePdf} className="text-3xl text- primary" />75 <div className="bg-white rounded-full p-4"> 76 <FontAwesomeIcon icon={faFilePdf} className="text-3xl text-[#0272D1]" /> 77 77 </div> 78 78 <div> … … 86 86 87 87 {/* Document Request Form */} 88 <div className="bg- white rounded-xl p-6 shadow-sm border border-gray-100mb-8">89 <h2 className="text-lg font-semibold text- gray-900mb-6 flex items-center gap-2">88 <div className="bg-card rounded-xl p-6 shadow-sm border border-border mb-8"> 89 <h2 className="text-lg font-semibold text-card-foreground mb-6 flex items-center gap-2"> 90 90 <FontAwesomeIcon icon={faFileText} className="text-primary" /> 91 91 {t('new_document_request', 'Ново барање за документ')} … … 95 95 {/* Document Type Selection */} 96 96 <div> 97 <label className="block text-sm font-medium text- gray-700mb-2">97 <label className="block text-sm font-medium text-muted-foreground mb-2"> 98 98 {t('select_document', 'Избери документ')}: 99 99 </label> … … 101 101 <button 102 102 onClick={() => setIsDropdownOpen(!isDropdownOpen)} 103 className="w-full bg- white border border-gray-300rounded-lg px-4 py-3 text-left focus:outline-none focus:ring-2 focus:ring-primary focus:border-primary"103 className="w-full bg-card border border-border rounded-lg px-4 py-3 text-left focus:outline-none focus:ring-2 focus:ring-primary focus:border-primary" 104 104 > 105 105 <div className="flex items-center justify-between"> 106 <span className="text-sm text- gray-900truncate">106 <span className="text-sm text-card-foreground truncate"> 107 107 {selectedDocument ? t(selectedDocument.id) : t('select_document', 'Избери документ')} 108 108 </span> 109 109 <FontAwesomeIcon 110 110 icon={faChevronDown} 111 className={`w-4 h-4 text- gray-400transition-transform ml-2 flex-shrink-0 ${isDropdownOpen ? 'rotate-180' : ''}`}111 className={`w-4 h-4 text-muted-foreground transition-transform ml-2 flex-shrink-0 ${isDropdownOpen ? 'rotate-180' : ''}`} 112 112 /> 113 113 </div> … … 115 115 116 116 {isDropdownOpen && ( 117 <div className="absolute z-10 w-full mt-1 bg- white border border-gray-200rounded-lg shadow-lg max-h-80 overflow-y-auto">117 <div className="absolute z-10 w-full mt-1 bg-card border border-border rounded-lg shadow-lg max-h-80 overflow-y-auto"> 118 118 {documentsData.documentTypes.map((docType) => ( 119 119 <button … … 123 123 setIsDropdownOpen(false); 124 124 }} 125 className="w-full px-4 py-3 text-left text-sm hover:bg- gray-50 focus:outline-none focus:bg-gray-50 border-b border-gray-100last:border-b-0"125 className="w-full px-4 py-3 text-left text-sm hover:bg-accent focus:outline-none focus:bg-accent border-b border-border last:border-b-0" 126 126 > 127 <div className="font-medium text- gray-900">{t(docType.id)}</div>127 <div className="font-medium text-card-foreground">{t(docType.id)}</div> 128 128 {docType.price > 0 && ( 129 129 <div className="text-xs text-blue-600 mt-1">{t('price', 'Цена')}: {docType.price} мкд</div> … … 138 138 {/* Comment Section */} 139 139 <div> 140 <label className="block text-sm font-medium text- gray-700mb-2">140 <label className="block text-sm font-medium text-muted-foreground mb-2"> 141 141 {t('comment', 'Коментар')}: 142 142 </label> … … 145 145 onChange={(e) => setComment(e.target.value)} 146 146 rows={4} 147 className="w-full border border- gray-300rounded-lg px-4 py-3 focus:outline-none focus:ring-2 focus:ring-primary focus:border-primary resize-none"147 className="w-full border border-border rounded-lg px-4 py-3 focus:outline-none focus:ring-2 focus:ring-primary focus:border-primary resize-none" 148 148 placeholder={t('add_comment', 'Додај коментар')} 149 149 /> … … 163 163 164 164 {/* Documents Table */} 165 <div className="bg- white rounded-xl shadow-sm border border-gray-100overflow-hidden">165 <div className="bg-card rounded-xl shadow-sm border border-border overflow-hidden"> 166 166 <div className="bg-primary text-white px-6 py-4"> 167 167 <h2 className="text-xl font-bold">{t('my_documents', 'Мои документи')}</h2> … … 170 170 <div className="overflow-x-auto"> 171 171 <table className="w-full"> 172 <thead className="bg- gray-50">172 <thead className="bg-accent"> 173 173 <tr> 174 <th className="px-4 py-4 text-left text-xs font-medium text- gray-500uppercase tracking-wider">#</th>175 <th className="px-4 py-4 text-left text-xs font-medium text- gray-500uppercase tracking-wider">{t('archive', 'Архива')}</th>176 <th className="px-4 py-4 text-left text-xs font-medium text- gray-500uppercase tracking-wider">{t('date', 'Датум')}</th>177 <th className="px-4 py-4 text-left text-xs font-medium text- gray-500uppercase tracking-wider">{t('request', 'Барање')}</th>178 <th className="px-4 py-4 text-right text-xs font-medium text- gray-500uppercase tracking-wider">{t('price', 'Цена')}</th>179 <th className="px-4 py-4 text-center text-xs font-medium text- gray-500uppercase tracking-wider">{t('paid', 'Платено')}</th>180 <th className="px-4 py-4 text-center text-xs font-medium text- gray-500uppercase tracking-wider">{t('document', 'Документ')}</th>181 <th className="px-4 py-4 text-center text-xs font-medium text- gray-500uppercase tracking-wider">{t('pay_online', 'Плати онлајн')}</th>182 <th className="px-4 py-4 text-center text-xs font-medium text- gray-500uppercase tracking-wider">{t('status', 'Статус')}</th>183 <th className="px-4 py-4 text-left text-xs font-medium text- gray-500uppercase tracking-wider">{t('comment', 'Коментар')}</th>174 <th className="px-4 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">#</th> 175 <th className="px-4 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('archive', 'Архива')}</th> 176 <th className="px-4 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('date', 'Датум')}</th> 177 <th className="px-4 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('request', 'Барање')}</th> 178 <th className="px-4 py-4 text-right text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('price', 'Цена')}</th> 179 <th className="px-4 py-4 text-center text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('paid', 'Платено')}</th> 180 <th className="px-4 py-4 text-center text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('document', 'Документ')}</th> 181 <th className="px-4 py-4 text-center text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('pay_online', 'Плати онлајн')}</th> 182 <th className="px-4 py-4 text-center text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('status', 'Статус')}</th> 183 <th className="px-4 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('comment', 'Коментар')}</th> 184 184 </tr> 185 185 </thead> 186 <tbody className="divide-y divide- gray-100">186 <tbody className="divide-y divide-border"> 187 187 {currentDocuments.map((document) => ( 188 <tr key={document.id} className="hover:bg- gray-50transition-colors">189 <TableCell className="font-medium text- gray-900">{document.id}</TableCell>188 <tr key={document.id} className="hover:bg-accent transition-colors"> 189 <TableCell className="font-medium text-card-foreground">{document.id}</TableCell> 190 190 <TableCell className="font-mono text-sm text-primary font-medium">{document.archive}</TableCell> 191 <TableCell className="text- gray-600">{document.date}</TableCell>192 <TableCell className="font-medium text- gray-900max-w-xs">191 <TableCell className="text-muted-foreground">{document.date}</TableCell> 192 <TableCell className="font-medium text-card-foreground max-w-xs"> 193 193 {t(document.request)} 194 194 </TableCell> … … 210 210 <FontAwesomeIcon icon={faCheckCircle} className="w-5 h-5 text-green-600" /> 211 211 ) : ( 212 <span className="text- gray-400">{t('none', '—')}</span>212 <span className="text-muted-foreground">{t('none', '—')}</span> 213 213 )} 214 214 </TableCell> … … 218 218 <TableCell> 219 219 {document.comment || ( 220 <span className="text- gray-400">{t('none', '—')}</span>220 <span className="text-muted-foreground">{t('none', '—')}</span> 221 221 )} 222 222 </TableCell> … … 228 228 229 229 {/* Pagination */} 230 <div className="bg- gray-50 px-6 py-4 flex items-center justify-between border-t border-gray-200">231 <div className="flex items-center gap-4 text-sm text- gray-700">230 <div className="bg-accent px-6 py-4 flex items-center justify-between border-t border-border"> 231 <div className="flex items-center gap-4 text-sm text-muted-foreground"> 232 232 <div className="flex items-center gap-2"> 233 233 <span>{t('show_rows', 'Прикажи редови')}:</span> … … 235 235 value={recordsPerPage} 236 236 onChange={(e) => setRecordsPerPage(Number(e.target.value))} 237 className="border border- gray-300rounded px-2 py-1 text-sm focus:outline-none focus:ring-1 focus:ring-primary"237 className="border border-border rounded px-2 py-1 text-sm focus:outline-none focus:ring-1 focus:ring-primary" 238 238 > 239 239 <option value={15}>15</option> … … 249 249 value={currentPage} 250 250 onChange={(e) => setCurrentPage(Number(e.target.value))} 251 className="w-12 border border- gray-300rounded px-2 py-1 text-sm text-center focus:outline-none focus:ring-1 focus:ring-primary"251 className="w-12 border border-border rounded px-2 py-1 text-sm text-center focus:outline-none focus:ring-1 focus:ring-primary" 252 252 /> {t('of', 'од')} {totalPages} 253 253 </div> … … 258 258 onClick={() => setCurrentPage(1)} 259 259 disabled={currentPage === 1} 260 className="p-2 text- gray-500hover:text-primary disabled:opacity-50 disabled:cursor-not-allowed"260 className="p-2 text-muted-foreground hover:text-primary disabled:opacity-50 disabled:cursor-not-allowed" 261 261 > 262 262 <FontAwesomeIcon icon={faAngleDoubleLeft} className="w-4 h-4" /> … … 265 265 onClick={() => setCurrentPage(Math.max(1, currentPage - 1))} 266 266 disabled={currentPage === 1} 267 className="p-2 text- gray-500hover:text-primary disabled:opacity-50 disabled:cursor-not-allowed"267 className="p-2 text-muted-foreground hover:text-primary disabled:opacity-50 disabled:cursor-not-allowed" 268 268 > 269 269 <FontAwesomeIcon icon={faChevronLeft} className="w-4 h-4" /> … … 275 275 onClick={() => setCurrentPage(Math.min(totalPages, currentPage + 1))} 276 276 disabled={currentPage === totalPages} 277 className="p-2 text- gray-500hover:text-primary disabled:opacity-50 disabled:cursor-not-allowed"277 className="p-2 text-muted-foreground hover:text-primary disabled:opacity-50 disabled:cursor-not-allowed" 278 278 > 279 279 <FontAwesomeIcon icon={faChevronRight} className="w-4 h-4" /> … … 282 282 onClick={() => setCurrentPage(totalPages)} 283 283 disabled={currentPage === totalPages} 284 className="p-2 text- gray-500hover:text-primary disabled:opacity-50 disabled:cursor-not-allowed"284 className="p-2 text-muted-foreground hover:text-primary disabled:opacity-50 disabled:cursor-not-allowed" 285 285 > 286 286 <FontAwesomeIcon icon={faAngleDoubleRight} className="w-4 h-4" /> 287 287 </button> 288 <span className="ml-4 text-sm text- gray-700">288 <span className="ml-4 text-sm text-muted-foreground"> 289 289 {t('last', 'Последна')} 290 290 </span> 291 291 </div> 292 292 293 <div className="text-sm text- gray-700">293 <div className="text-sm text-muted-foreground"> 294 294 {t('total', 'Вкупно')}: {documents.length} 295 295 </div> … … 309 309 {/* Statistics Cards */} 310 310 <div className="grid grid-cols-1 md:grid-cols-3 gap-6 mt-8"> 311 <div className="bg- white rounded-xl p-6 shadow-sm border border-gray-100">311 <div className="bg-card rounded-xl p-6 shadow-sm border border-border"> 312 312 <div className="flex items-center gap-4"> 313 313 <div className="bg-blue-100 text-blue-600 rounded-full p-3"> … … 315 315 </div> 316 316 <div> 317 <h3 className="text-lg font-bold text- gray-900">{t('total_documents', 'Вкупно документи')}</h3>317 <h3 className="text-lg font-bold text-card-foreground">{t('total_documents', 'Вкупно документи')}</h3> 318 318 <p className="text-2xl font-bold text-blue-600"> 319 319 {documents.length} … … 323 323 </div> 324 324 325 <div className="bg- white rounded-xl p-6 shadow-sm border border-gray-100">325 <div className="bg-card rounded-xl p-6 shadow-sm border border-border"> 326 326 <div className="flex items-center gap-4"> 327 327 <div className="bg-green-100 text-green-600 rounded-full p-3"> … … 329 329 </div> 330 330 <div> 331 <h3 className="text-lg font-bold text- gray-900">{t('approved', 'Одобрени')}</h3>331 <h3 className="text-lg font-bold text-card-foreground">{t('approved', 'Одобрени')}</h3> 332 332 <p className="text-2xl font-bold text-green-600"> 333 333 {documents.filter(doc => doc.status === "approved").length} … … 337 337 </div> 338 338 339 <div className="bg- white rounded-xl p-6 shadow-sm border border-gray-100">339 <div className="bg-card rounded-xl p-6 shadow-sm border border-border"> 340 340 <div className="flex items-center gap-4"> 341 341 <div className="bg-yellow-100 text-yellow-600 rounded-full p-3"> … … 343 343 </div> 344 344 <div> 345 <h3 className="text-lg font-bold text- gray-900">{t('total_price', 'Вкупна цена')}</h3>345 <h3 className="text-lg font-bold text-card-foreground">{t('total_price', 'Вкупна цена')}</h3> 346 346 <p className="text-2xl font-bold text-yellow-600"> 347 347 {documents.reduce((sum, doc) => sum + doc.price, 0).toFixed(2)} {t('mkd', 'мкд')} -
src/app/students/layout.tsx
r50f2fb4 rba52069 32 32 }>) { 33 33 return ( 34 <html lang="en"> 35 <body className={`${geistSans.variable} ${geistMono.variable} antialiased`}> 36 <div className="mx-auto max-w-6xl px-4"> 37 <Header /> 38 <Navbar /> 39 {children} 40 </div> 41 </body> 42 </html> 34 <div className={`${geistSans.variable} ${geistMono.variable} antialiased`}> 35 <Header /> 36 <Navbar /> 37 {children} 38 </div> 43 39 ); 44 40 } -
src/app/students/profile/page.tsx
r50f2fb4 rba52069 98 98 const { t } = useTranslation(); 99 99 return ( 100 <div className="flex justify-between items-center py-3 border-b border- gray-100last:border-b-0">101 <div className="flex items-center gap-2 text- gray-600font-medium">100 <div className="flex justify-between items-center py-3 border-b border-border last:border-b-0"> 101 <div className="flex items-center gap-2 text-muted-foreground font-medium"> 102 102 {icon && <FontAwesomeIcon icon={icon} className="w-4 h-4" />} 103 103 <span>{t(label)}:</span> 104 104 </div> 105 <div className="text- gray-900font-semibold text-right max-w-xs break-words">105 <div className="text-card-foreground font-semibold text-right max-w-xs break-words"> 106 106 {value || t('n_a')} 107 107 </div> … … 119 119 const { t } = useTranslation(); 120 120 return ( 121 <div className="bg- white rounded-xl shadow-sm border border-gray-100overflow-hidden">121 <div className="bg-card rounded-xl shadow-sm border border-border overflow-hidden"> 122 122 <div className="bg-primary text-white px-6 py-4"> 123 123 <div className="flex items-center gap-3"> … … 187 187 return ( 188 188 <div className="min-h-screen pb-8"> 189 <div className="bg- white rounded-xl shadow-sm border border-gray-100p-6">189 <div className="bg-card rounded-xl shadow-sm border border-border p-6"> 190 190 {t('loading')} 191 191 </div> … … 212 212 <div className="flex items-center gap-6"> 213 213 <div className="relative"> 214 <div className="w-20 h-20 bg-white bg-opacity-20 rounded-full flex items-center justify-center border-2 border-white border-opacity-30">215 <FontAwesomeIcon icon={faUser} className="text-3xl text- primary" />214 <div className="w-20 h-20 bg-white rounded-full flex items-center justify-center border-2 border-white shadow-lg"> 215 <FontAwesomeIcon icon={faUser} className="text-3xl text-[#0272D1]" /> 216 216 </div> 217 217 <div className="absolute -bottom-1 -right-1 w-6 h-6 bg-green-500 rounded-full border-2 border-white"></div> -
src/app/students/semesters/page.tsx
r50f2fb4 rba52069 49 49 50 50 const TableCell = ({ children, className = "" }: TableCellProps) => ( 51 <td className={`px-4 py-3 text-sm border-b border- gray-100${className}`}>51 <td className={`px-4 py-3 text-sm border-b border-border ${className}`}> 52 52 {children} 53 53 </td> … … 66 66 } 67 67 return ( 68 <span className={`${baseClasses} bg- gray-100text-gray-800`}>68 <span className={`${baseClasses} bg-accent text-gray-800`}> 69 69 {t(status) || status} 70 70 </span> … … 87 87 ); 88 88 } 89 return <span className="text- gray-400">—</span>;89 return <span className="text-muted-foreground">—</span>; 90 90 }; 91 91 … … 163 163 return ( 164 164 <div className="min-h-screen pb-8"> 165 <div className="bg- white rounded-xl shadow-sm border border-gray-100p-6">165 <div className="bg-card rounded-xl shadow-sm border border-border p-6"> 166 166 {t('loading')} 167 167 </div> … … 185 185 <div className="bg-primary text-white rounded-xl p-8 mb-8"> 186 186 <div className="flex items-center gap-4"> 187 <div className="bg-white bg-opacity-20rounded-full p-4">188 <FontAwesomeIcon icon={faCalendarAlt} className="text-3xl text- primary" />187 <div className="bg-white rounded-full p-4"> 188 <FontAwesomeIcon icon={faCalendarAlt} className="text-3xl text-[#0272D1]" /> 189 189 </div> 190 190 <div> … … 198 198 199 199 {/* Table Container */} 200 <div className="bg- white rounded-xl shadow-sm border border-gray-100overflow-hidden">200 <div className="bg-card rounded-xl shadow-sm border border-border overflow-hidden"> 201 201 <div className="bg-primary text-white px-6 py-4"> 202 202 <h2 className="text-xl font-bold">{t('semesters_list')}</h2> … … 205 205 <div className="overflow-x-auto"> 206 206 <table className="w-full"> 207 <thead className="bg- gray-50">207 <thead className="bg-accent"> 208 208 <tr> 209 <th className="px-4 py-4 text-left text-xs font-medium text- gray-500uppercase tracking-wider">#</th>210 <th className="px-4 py-4 text-left text-xs font-medium text- gray-500uppercase tracking-wider">{t('semester')}</th>211 <th className="px-4 py-4 text-left text-xs font-medium text- gray-500uppercase tracking-wider">{t('direction')}</th>212 <th className="px-4 py-4 text-left text-xs font-medium text- gray-500uppercase tracking-wider">{t('quota')}</th>213 <th className="px-4 py-4 text-left text-xs font-medium text- gray-500uppercase tracking-wider">{t('note')}</th>214 <th className="px-4 py-4 text-left text-xs font-medium text- gray-500uppercase tracking-wider">{t('student_com')}</th>215 <th className="px-4 py-4 text-left text-xs font-medium text- gray-500uppercase tracking-wider">{t('sum')}</th>216 <th className="px-4 py-4 text-left text-xs font-medium text- gray-500uppercase tracking-wider">{t('paid')}</th>217 <th className="px-4 py-4 text-left text-xs font-medium text- gray-500uppercase tracking-wider">{t('ukim')}</th>218 <th className="px-4 py-4 text-left text-xs font-medium text- gray-500uppercase tracking-wider">{t('created_on')}</th>219 <th className="px-4 py-4 text-left text-xs font-medium text- gray-500uppercase tracking-wider">{t('date_changed')}</th>220 <th className="px-4 py-4 text-left text-xs font-medium text- gray-500uppercase tracking-wider">{t('credits')}</th>221 <th className="px-4 py-4 text-left text-xs font-medium text- gray-500uppercase tracking-wider">{t('type')}</th>222 <th className="px-4 py-4 text-left text-xs font-medium text- gray-500uppercase tracking-wider">{t('doc')}</th>223 <th className="px-4 py-4 text-left text-xs font-medium text- gray-500uppercase tracking-wider">{t('doc1')}</th>224 <th className="px-4 py-4 text-left text-xs font-medium text- gray-500uppercase tracking-wider">{t('verified')}</th>225 <th className="px-4 py-4 text-left text-xs font-medium text- gray-500uppercase tracking-wider">{t('taxes')}</th>226 <th className="px-4 py-4 text-left text-xs font-medium text- gray-500uppercase tracking-wider">{t('signatures')}</th>227 <th className="px-4 py-4 text-left text-xs font-medium text- gray-500uppercase tracking-wider">{t('status')}</th>228 <th className="px-4 py-4 text-left text-xs font-medium text- gray-500uppercase tracking-wider">{t('completed')}</th>209 <th className="px-4 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">#</th> 210 <th className="px-4 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('semester')}</th> 211 <th className="px-4 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('direction')}</th> 212 <th className="px-4 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('quota')}</th> 213 <th className="px-4 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('note')}</th> 214 <th className="px-4 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('student_com')}</th> 215 <th className="px-4 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('sum')}</th> 216 <th className="px-4 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('paid')}</th> 217 <th className="px-4 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('ukim')}</th> 218 <th className="px-4 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('created_on')}</th> 219 <th className="px-4 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('date_changed')}</th> 220 <th className="px-4 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('credits')}</th> 221 <th className="px-4 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('type')}</th> 222 <th className="px-4 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('doc')}</th> 223 <th className="px-4 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('doc1')}</th> 224 <th className="px-4 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('verified')}</th> 225 <th className="px-4 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('taxes')}</th> 226 <th className="px-4 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('signatures')}</th> 227 <th className="px-4 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('status')}</th> 228 <th className="px-4 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('completed')}</th> 229 229 </tr> 230 230 </thead> 231 <tbody className="divide-y divide- gray-100">231 <tbody className="divide-y divide-border"> 232 232 {semesters.map((semester) => ( 233 <tr key={semester.id} className="hover:bg- gray-50transition-colors">234 <TableCell className="font-medium text- gray-900">{semester.id}</TableCell>233 <tr key={semester.id} className="hover:bg-accent transition-colors"> 234 <TableCell className="font-medium text-card-foreground">{semester.id}</TableCell> 235 235 <TableCell className="font-medium text-primary">{semester.semester}</TableCell> 236 236 <TableCell>{semester.direction}</TableCell> … … 246 246 </span> 247 247 ) : ( 248 <span className="text- gray-400">—</span>248 <span className="text-muted-foreground">—</span> 249 249 )} 250 250 </TableCell> … … 255 255 </span> 256 256 ) : ( 257 <span className="text- gray-400">—</span>257 <span className="text-muted-foreground">—</span> 258 258 )} 259 259 </TableCell> … … 265 265 </span> 266 266 ) : ( 267 <span className="text- gray-400">—</span>267 <span className="text-muted-foreground">—</span> 268 268 )} 269 269 </TableCell> … … 275 275 </span> 276 276 ) : ( 277 <span className="text- gray-400">—</span>277 <span className="text-muted-foreground">—</span> 278 278 )} 279 279 </TableCell> … … 282 282 <span className="text-blue-600">{semester.ukim}</span> 283 283 ) : ( 284 <span className="text- gray-400">—</span>285 )} 286 </TableCell> 287 <TableCell className="text- gray-600">{semester.createdOn}</TableCell>288 <TableCell className="text- gray-600">{semester.dateChanged}</TableCell>284 <span className="text-muted-foreground">—</span> 285 )} 286 </TableCell> 287 <TableCell className="text-muted-foreground">{semester.createdOn}</TableCell> 288 <TableCell className="text-muted-foreground">{semester.dateChanged}</TableCell> 289 289 <TableCell className="font-medium text-primary">{semester.credits}</TableCell> 290 290 <TableCell> … … 331 331 {/* Summary Cards */} 332 332 <div className="grid grid-cols-1 md:grid-cols-3 gap-6 mt-8"> 333 <div className="bg- white rounded-xl p-6 shadow-sm border border-gray-100">333 <div className="bg-card rounded-xl p-6 shadow-sm border border-border"> 334 334 <div className="flex items-center gap-4"> 335 335 <div className="bg-green-100 text-green-600 rounded-full p-3"> … … 337 337 </div> 338 338 <div> 339 <h3 className="text-lg font-bold text- gray-900">{t('completed_semesters')}</h3>339 <h3 className="text-lg font-bold text-card-foreground">{t('completed_semesters')}</h3> 340 340 <p className="text-2xl font-bold text-green-600"> 341 341 {semesters.filter(s => s.completed !== "Не").length} … … 345 345 </div> 346 346 347 <div className="bg- white rounded-xl p-6 shadow-sm border border-gray-100">347 <div className="bg-card rounded-xl p-6 shadow-sm border border-border"> 348 348 <div className="flex items-center gap-4"> 349 349 <div className="bg-blue-100 text-blue-600 rounded-full p-3"> … … 351 351 </div> 352 352 <div> 353 <h3 className="text-lg font-bold text- gray-900">{t('verified_semesters')}</h3>353 <h3 className="text-lg font-bold text-card-foreground">{t('verified_semesters')}</h3> 354 354 <p className="text-2xl font-bold text-blue-600"> 355 355 {semesters.filter(s => s.verified === "Да").length} … … 359 359 </div> 360 360 361 <div className="bg- white rounded-xl p-6 shadow-sm border border-gray-100">361 <div className="bg-card rounded-xl p-6 shadow-sm border border-border"> 362 362 <div className="flex items-center gap-4"> 363 363 <div className="bg-primary text-white rounded-full p-3"> … … 365 365 </div> 366 366 <div> 367 <h3 className="text-lg font-bold text- gray-900">{t('total_semesters')}</h3>367 <h3 className="text-lg font-bold text-card-foreground">{t('total_semesters')}</h3> 368 368 <p className="text-2xl font-bold text-primary"> 369 369 {semesters.length} -
src/app/students/subjects/page.tsx
r50f2fb4 rba52069 142 142 143 143 const TableCell = ({ children, className = "" }: TableCellProps) => ( 144 <td className={`px-4 py-3 text-sm border-b border- gray-200${className}`}>144 <td className={`px-4 py-3 text-sm border-b border-border ${className}`}> 145 145 {children} 146 146 </td> … … 164 164 } 165 165 return ( 166 <span className={`${baseClasses} bg- gray-100text-gray-800`}>166 <span className={`${baseClasses} bg-accent text-gray-800`}> 167 167 {t(status) || status} 168 168 </span> … … 275 275 return ( 276 276 <div className="min-h-screen pb-8"> 277 <div className="bg- white rounded-xl shadow-sm border border-gray-100p-6">277 <div className="bg-card rounded-xl shadow-sm border border-border p-6"> 278 278 {t('loading')} 279 279 </div> … … 305 305 <div className="bg-primary text-white rounded-xl p-8 mb-8"> 306 306 <div className="flex items-center gap-4"> 307 <div className="bg-white bg-opacity-20rounded-full p-4">308 <FontAwesomeIcon icon={faBook} className="text-3xl text- primary" />307 <div className="bg-white rounded-full p-4"> 308 <FontAwesomeIcon icon={faBook} className="text-3xl text-[#0272D1]" /> 309 309 </div> 310 310 <div> … … 324 324 325 325 {/* Status Card */} 326 <div className="bg- white rounded-xl p-6 shadow-sm border border-gray-100">327 <div className="text-sm text- gray-600mb-2">326 <div className="bg-card rounded-xl p-6 shadow-sm border border-border"> 327 <div className="text-sm text-muted-foreground mb-2"> 328 328 {t('status')}: <span className="text-primary font-semibold">{t('enrolled_by_student')}</span> 329 329 </div> 330 <div className="text-sm text- gray-600">330 <div className="text-sm text-muted-foreground"> 331 331 {t('ticket_number')}: <span className="font-semibold">{currentSemester.ticketNumber}</span> 332 332 </div> … … 334 334 335 335 {/* Semester Selection */} 336 <div className="bg- white rounded-xl p-6 shadow-sm border border-gray-100">337 <div className="text-sm text- gray-600mb-2">336 <div className="bg-card rounded-xl p-6 shadow-sm border border-border"> 337 <div className="text-sm text-muted-foreground mb-2"> 338 338 {t('debt_from_documents')}: <span className="font-semibold">{currentSemester.debt}</span> 339 339 </div> 340 340 341 341 <div className="relative mt-4"> 342 <label className="block text-sm font-medium text- gray-700mb-2">342 <label className="block text-sm font-medium text-muted-foreground mb-2"> 343 343 {t('select_semester')}: 344 344 </label> … … 346 346 <button 347 347 onClick={() => setIsDropdownOpen(!isDropdownOpen)} 348 className="w-full bg- white border border-gray-300rounded-lg px-4 py-3 text-left focus:outline-none focus:ring-2 focus:ring-primary focus:border-primary"348 className="w-full bg-card border border-border rounded-lg px-4 py-3 text-left focus:outline-none focus:ring-2 focus:ring-primary focus:border-primary" 349 349 > 350 350 <div className="flex items-center justify-between"> … … 354 354 <FontAwesomeIcon 355 355 icon={faChevronDown} 356 className={`w-4 h-4 text- gray-400transition-transform ${isDropdownOpen ? 'rotate-180' : ''}`}356 className={`w-4 h-4 text-muted-foreground transition-transform ${isDropdownOpen ? 'rotate-180' : ''}`} 357 357 /> 358 358 </div> … … 360 360 361 361 {isDropdownOpen && ( 362 <div className="absolute z-10 w-full mt-1 bg- white border border-gray-200rounded-lg shadow-lg">362 <div className="absolute z-10 w-full mt-1 bg-card border border-border rounded-lg shadow-lg"> 363 363 {subjectsData.semesters.map((semester) => ( 364 364 <button … … 368 368 setIsDropdownOpen(false); 369 369 }} 370 className="w-full px-4 py-3 text-left text-sm hover:bg- gray-50 focus:outline-none focus:bg-gray-50first:rounded-t-lg last:rounded-b-lg"370 className="w-full px-4 py-3 text-left text-sm hover:bg-accent focus:outline-none focus:bg-accent first:rounded-t-lg last:rounded-b-lg" 371 371 > 372 <div className="font-medium text- gray-900">{semester.name}</div>373 <div className="text-xs text- gray-500">{t('status')}: {semester.status}</div>372 <div className="font-medium text-card-foreground">{semester.name}</div> 373 <div className="text-xs text-muted-foreground">{t('status')}: {semester.status}</div> 374 374 </button> 375 375 ))} … … 387 387 388 388 {/* Enrolled Subjects */} 389 <div className="bg- white rounded-xl p-6 shadow-sm border border-gray-100">390 <h3 className="font-semibold text- gray-900mb-3 flex items-center gap-2">389 <div className="bg-card rounded-xl p-6 shadow-sm border border-border"> 390 <h3 className="font-semibold text-card-foreground mb-3 flex items-center gap-2"> 391 391 <FontAwesomeIcon icon={faBook} className="w-4 h-4 text-primary" /> 392 392 {t('enrolled_subjects')} … … 400 400 {/* Right Column - Financial Information */} 401 401 <div className="lg:col-span-2"> 402 <div className="bg- white rounded-xl shadow-sm border border-gray-100overflow-hidden">402 <div className="bg-card rounded-xl shadow-sm border border-border overflow-hidden"> 403 403 <div className="bg-primary text-white px-6 py-4"> 404 404 <h2 className="text-xl font-bold flex items-center gap-2"> … … 413 413 {/* Left Financial Column */} 414 414 <div className="space-y-4"> 415 <div className="flex justify-between items-center py-2 border-b border- gray-100">416 <span className="text- gray-600">{t('sum')}:</span>415 <div className="flex justify-between items-center py-2 border-b border-border"> 416 <span className="text-muted-foreground">{t('sum')}:</span> 417 417 <span className="font-semibold text-primary">{currentSemester.financialInfo.sum}</span> 418 418 </div> 419 <div className="flex justify-between items-center py-2 border-b border- gray-100">420 <span className="text- gray-600">{t('paid')}:</span>419 <div className="flex justify-between items-center py-2 border-b border-border"> 420 <span className="text-muted-foreground">{t('paid')}:</span> 421 421 <span className="font-semibold text-green-600">{currentSemester.financialInfo.paid}</span> 422 422 </div> 423 <div className="flex justify-between items-center py-2 border-b border- gray-100">424 <span className="text- gray-600">{t('due')}:</span>423 <div className="flex justify-between items-center py-2 border-b border-border"> 424 <span className="text-muted-foreground">{t('due')}:</span> 425 425 <span className="font-semibold text-red-600">{currentSemester.financialInfo.due}</span> 426 426 </div> … … 433 433 {/* Right Financial Column */} 434 434 <div className="space-y-4"> 435 <div className="flex justify-between items-center py-2 border-b border- gray-100">436 <span className="text- gray-600">{t('credits')}:</span>435 <div className="flex justify-between items-center py-2 border-b border-border"> 436 <span className="text-muted-foreground">{t('credits')}:</span> 437 437 <span className="font-semibold text-primary">{currentSemester.financialInfo.credits}</span> 438 438 </div> 439 <div className="flex justify-between items-center py-2 border-b border- gray-100">440 <span className="text- gray-600">{t('mksa')}:</span>439 <div className="flex justify-between items-center py-2 border-b border-border"> 440 <span className="text-muted-foreground">{t('mksa')}:</span> 441 441 <span className="font-semibold">{currentSemester.financialInfo.MKSA}</span> 442 442 </div> 443 <div className="flex justify-between items-center py-2 border-b border- gray-100">444 <span className="text- gray-600">{t('electronic_registration')}:</span>443 <div className="flex justify-between items-center py-2 border-b border-border"> 444 <span className="text-muted-foreground">{t('electronic_registration')}:</span> 445 445 <span className="font-semibold">{currentSemester.financialInfo.electronicRegistration}</span> 446 446 </div> 447 <div className="flex justify-between items-center py-2 border-b border- gray-100">448 <span className="text- gray-600">{t('eukim')}:</span>447 <div className="flex justify-between items-center py-2 border-b border-border"> 448 <span className="text-muted-foreground">{t('eukim')}:</span> 449 449 <span className="font-semibold">{currentSemester.financialInfo.eUKIM}</span> 450 450 </div> 451 <div className="flex justify-between items-center py-2 border-b border- gray-100">452 <span className="text- gray-600">{t('bank_provision')}:</span>451 <div className="flex justify-between items-center py-2 border-b border-border"> 452 <span className="text-muted-foreground">{t('bank_provision')}:</span> 453 453 <span className="font-semibold">{currentSemester.financialInfo.bankProvision}</span> 454 454 </div> … … 465 465 466 466 {/* Subjects Table */} 467 <div className="bg- white rounded-xl shadow-sm border border-gray-100overflow-hidden">467 <div className="bg-card rounded-xl shadow-sm border border-border overflow-hidden"> 468 468 <div className="bg-primary text-white px-6 py-4"> 469 469 <h2 className="text-xl font-bold">{t('subjects_list')}</h2> … … 472 472 <div className="overflow-x-auto"> 473 473 <table className="w-full"> 474 <thead className="bg- gray-50">474 <thead className="bg-accent"> 475 475 <tr> 476 <th className="px-4 py-4 text-left text-xs font-medium text- gray-500uppercase tracking-wider">#</th>477 <th className="px-4 py-4 text-left text-xs font-medium text- gray-500uppercase tracking-wider">{t('code')}</th>478 <th className="px-4 py-4 text-left text-xs font-medium text- gray-500uppercase tracking-wider">{t('hours')}</th>479 <th className="px-4 py-4 text-left text-xs font-medium text- gray-500uppercase tracking-wider">{t('which_time')}</th>480 <th className="px-4 py-4 text-left text-xs font-medium text- gray-500uppercase tracking-wider">{t('subject')}</th>481 <th className="px-4 py-4 text-left text-xs font-medium text- gray-500uppercase tracking-wider">{t('semester')}</th>482 <th className="px-4 py-4 text-left text-xs font-medium text- gray-500uppercase tracking-wider">{t('status')}</th>483 <th className="px-4 py-4 text-left text-xs font-medium text- gray-500uppercase tracking-wider">{t('signature')}</th>484 <th className="px-4 py-4 text-left text-xs font-medium text- gray-500uppercase tracking-wider">{t('group')}</th>485 <th className="px-4 py-4 text-left text-xs font-medium text- gray-500uppercase tracking-wider">{t('professor')}</th>476 <th className="px-4 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">#</th> 477 <th className="px-4 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('code')}</th> 478 <th className="px-4 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('hours')}</th> 479 <th className="px-4 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('which_time')}</th> 480 <th className="px-4 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('subject')}</th> 481 <th className="px-4 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('semester')}</th> 482 <th className="px-4 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('status')}</th> 483 <th className="px-4 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('signature')}</th> 484 <th className="px-4 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('group')}</th> 485 <th className="px-4 py-4 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider">{t('professor')}</th> 486 486 </tr> 487 487 </thead> 488 <tbody className="divide-y divide- gray-100">488 <tbody className="divide-y divide-border"> 489 489 {currentSubjects.map((subject: Subject) => ( 490 <tr key={subject.id} className="hover:bg- gray-50transition-colors">491 <TableCell className="font-medium text- gray-900">{subject.id}</TableCell>490 <tr key={subject.id} className="hover:bg-accent transition-colors"> 491 <TableCell className="font-medium text-card-foreground">{subject.id}</TableCell> 492 492 <TableCell className="font-mono text-sm text-primary font-medium">{subject.code}</TableCell> 493 493 <TableCell className="font-medium">{subject.hours}</TableCell> 494 494 <TableCell className="text-center font-medium">{subject.kojPat}</TableCell> 495 <TableCell className="font-medium text- gray-900max-w-xs">495 <TableCell className="font-medium text-card-foreground max-w-xs"> 496 496 <div className="flex items-center gap-2"> 497 497 <FontAwesomeIcon icon={faBook} className="w-4 h-4 text-primary" /> … … 505 505 <TableCell className="text-center"> 506 506 {subject.signature ? t(subject.signature, subject.signature) : ( 507 <span className="text- gray-400">—</span>507 <span className="text-muted-foreground">—</span> 508 508 )} 509 509 </TableCell> 510 510 <TableCell className="text-center"> 511 511 {subject.group ? t(subject.group, subject.group) : ( 512 <span className="text- gray-400">—</span>512 <span className="text-muted-foreground">—</span> 513 513 )} 514 514 </TableCell> 515 515 <TableCell> 516 516 {subject.professor ? t(subject.professor, subject.professor) : ( 517 <span className="text- gray-400">—</span>517 <span className="text-muted-foreground">—</span> 518 518 )} 519 519 </TableCell> -
src/components/LanguageSwitcher.tsx
r50f2fb4 rba52069 13 13 <button 14 14 onClick={() => changeLanguage('mk')} 15 className={`px-3 py-1 rounded border-2 text-sm font-semibold transition-all duration-150 ${i18n.language === 'mk' ? 'border- blue-600 text-blue-700 bg-blue-50' : 'border-gray-300 text-gray-700 bg-white hover:border-blue-400 hover:text-blue-600'}`}15 className={`px-3 py-1 rounded border-2 text-sm font-semibold transition-all duration-150 ${i18n.language === 'mk' ? 'border-primary text-primary bg-accent' : 'border-border text-muted-foreground bg-card hover:border-primary hover:text-primary'}`} 16 16 aria-label="Macedonian" 17 17 > … … 20 20 <button 21 21 onClick={() => changeLanguage('en')} 22 className={`px-3 py-1 rounded border-2 text-sm font-semibold transition-all duration-150 ${i18n.language === 'en' ? 'border- blue-600 text-blue-700 bg-blue-50' : 'border-gray-300 text-gray-700 bg-white hover:border-blue-400 hover:text-blue-600'}`}22 className={`px-3 py-1 rounded border-2 text-sm font-semibold transition-all duration-150 ${i18n.language === 'en' ? 'border-primary text-primary bg-accent' : 'border-border text-muted-foreground bg-card hover:border-primary hover:text-primary'}`} 23 23 aria-label="English" 24 24 > -
src/components/exams.tsx
r50f2fb4 rba52069 116 116 117 117 const getGradeColor = (grade: number) => { 118 if (grade >= 9) return "bg-green- 100 text-green-800 border-green-200";119 if (grade >= 8) return "bg-yellow- 100 text-yellow-800 border-yellow-200";120 if (grade >= 6) return "bg-orange- 100 text-orange-800 border-orange-200";121 return "bg-red- 100 text-red-800 border-red-200";118 if (grade >= 9) return "bg-green-500/10 text-green-600 dark:text-green-400 border-green-500/20"; 119 if (grade >= 8) return "bg-yellow-500/10 text-yellow-600 dark:text-yellow-400 border-yellow-500/20"; 120 if (grade >= 6) return "bg-orange-500/10 text-orange-600 dark:text-orange-400 border-orange-500/20"; 121 return "bg-red-500/10 text-red-600 dark:text-red-400 border-red-500/20"; 122 122 }; 123 123 … … 186 186 if (isLoading) { 187 187 return ( 188 <div className="bg- whiterounded-lg shadow-sm p-6">188 <div className="bg-card rounded-lg shadow-sm p-6"> 189 189 {t('loading', 'Loading...')} 190 190 </div> … … 194 194 if (errorMessage) { 195 195 return ( 196 <div className="bg- whiterounded-lg shadow-sm p-6">197 <div className="rounded-lg border border-red- 200 bg-red-50 px-4 py-3 text-sm text-red-700">196 <div className="bg-card rounded-lg shadow-sm p-6"> 197 <div className="rounded-lg border border-red-500/20 bg-red-500/10 px-4 py-3 text-sm text-red-600 dark:text-red-400"> 198 198 {t('failed_to_load_exams', errorMessage)} 199 199 </div> … … 203 203 204 204 return ( 205 <div className="bg- whiterounded-lg shadow-sm p-6 space-y-6">205 <div className="bg-card rounded-lg shadow-sm p-6 space-y-6"> 206 206 {/* Statistics Section */} 207 207 <div className="space-y-4"> … … 209 209 {/* Average Grade */} 210 210 <div className="text-center"> 211 <div className="text-3xl font-bold text- gray-900">{stats.average}</div>212 <div className="text-sm text- gray-500mt-1">{t('average', 'Просек')}</div>211 <div className="text-3xl font-bold text-card-foreground">{stats.average}</div> 212 <div className="text-sm text-muted-foreground mt-1">{t('average', 'Просек')}</div> 213 213 </div> 214 214 215 215 {/* Credits */} 216 216 <div className="text-center"> 217 <div className="text-3xl font-bold text- gray-900">217 <div className="text-3xl font-bold text-card-foreground"> 218 218 {stats.credits.current} 219 <span className="text-lg text- gray-400">/{stats.credits.total}</span>219 <span className="text-lg text-muted-foreground">/{stats.credits.total}</span> 220 220 </div> 221 <div className="text-sm text- gray-500mt-1">{t('credits', 'Кредити')}</div>221 <div className="text-sm text-muted-foreground mt-1">{t('credits', 'Кредити')}</div> 222 222 </div> 223 223 224 224 {/* Passed Exams */} 225 225 <div className="text-center"> 226 <div className="text-3xl font-bold text- gray-900">{stats.passed}</div>227 <div className="text-sm text- gray-500mt-1">{t('passed', 'Положени')}</div>226 <div className="text-3xl font-bold text-card-foreground">{stats.passed}</div> 227 <div className="text-sm text-muted-foreground mt-1">{t('passed', 'Положени')}</div> 228 228 </div> 229 229 230 230 {/* Remaining Exams */} 231 231 <div className="text-center"> 232 <div className="text-3xl font-bold text- gray-900">{stats.remaining}</div>233 <div className="text-sm text- gray-500mt-1">{t('remaining', 'Останато')}</div>232 <div className="text-3xl font-bold text-card-foreground">{stats.remaining}</div> 233 <div className="text-sm text-muted-foreground mt-1">{t('remaining', 'Останато')}</div> 234 234 </div> 235 235 </div> 236 236 237 237 {/* Progress Bar spanning entire statistics section */} 238 <div className="w-full bg- gray-200rounded-full h-2">238 <div className="w-full bg-secondary rounded-full h-2"> 239 239 <div 240 className="bg- blue-500h-2 rounded-full transition-all duration-300"240 className="bg-primary h-2 rounded-full transition-all duration-300" 241 241 style={{ width: `${creditsPercentage}%` }} 242 242 ></div> … … 246 246 {/* Exams Table */} 247 247 <div> 248 <h3 className="text-xl font-semibold text- gray-900mb-4">{t('exams', 'Испити')}</h3>248 <h3 className="text-xl font-semibold text-card-foreground mb-4">{t('exams', 'Испити')}</h3> 249 249 250 250 <div className="overflow-x-auto"> 251 251 <table className="min-w-full"> 252 252 <thead> 253 <tr className="border-b border- gray-200">254 <th className="text-left py-3 px-4 text-sm font-medium text- gray-500">#</th>255 <th className="text-left py-3 px-4 text-sm font-medium text- gray-500">{t('subject', 'Предмет')}</th>256 <th className="text-left py-3 px-4 text-sm font-medium text- gray-500">{t('semester', 'Семестар')}</th>257 <th className="text-left py-3 px-4 text-sm font-medium text- gray-500">{t('credits', 'Кредити')}</th>258 <th className="text-left py-3 px-4 text-sm font-medium text- gray-500">253 <tr className="border-b border-border"> 254 <th className="text-left py-3 px-4 text-sm font-medium text-muted-foreground">#</th> 255 <th className="text-left py-3 px-4 text-sm font-medium text-muted-foreground">{t('subject', 'Предмет')}</th> 256 <th className="text-left py-3 px-4 text-sm font-medium text-muted-foreground">{t('semester', 'Семестар')}</th> 257 <th className="text-left py-3 px-4 text-sm font-medium text-muted-foreground">{t('credits', 'Кредити')}</th> 258 <th className="text-left py-3 px-4 text-sm font-medium text-muted-foreground"> 259 259 <button 260 260 onClick={handleSortByDate} 261 className="flex items-center gap-2 px-2 py-1 rounded-md hover:bg- gray-100 hover:text-gray-900transition-all duration-200 transform hover:scale-105"261 className="flex items-center gap-2 px-2 py-1 rounded-md hover:bg-accent hover:text-accent-foreground transition-all duration-200 transform hover:scale-105" 262 262 > 263 263 {t('date', 'Датум')} … … 265 265 icon={getSortIcon('date')} 266 266 className={`text-xs transition-colors duration-200 ${ 267 sortField === 'date' ? 'text- blue-600' : 'text-gray-400 group-hover:text-gray-600'267 sortField === 'date' ? 'text-primary' : 'text-muted-foreground group-hover:text-foreground' 268 268 }`} 269 269 /> 270 270 </button> 271 271 </th> 272 <th className="text-left py-3 px-4 text-sm font-medium text- gray-500">272 <th className="text-left py-3 px-4 text-sm font-medium text-muted-foreground"> 273 273 <button 274 274 onClick={handleSortByGrade} 275 className="flex items-center gap-2 px-2 py-1 rounded-md hover:bg- gray-100 hover:text-gray-900transition-all duration-200 transform hover:scale-105"275 className="flex items-center gap-2 px-2 py-1 rounded-md hover:bg-accent hover:text-accent-foreground transition-all duration-200 transform hover:scale-105" 276 276 > 277 277 {t('grade', 'Оценка')} … … 279 279 icon={getSortIcon('grade')} 280 280 className={`text-xs transition-colors duration-200 ${ 281 sortField === 'grade' ? 'text- blue-600' : 'text-gray-400 group-hover:text-gray-600'281 sortField === 'grade' ? 'text-primary' : 'text-muted-foreground group-hover:text-foreground' 282 282 }`} 283 283 /> … … 286 286 </tr> 287 287 </thead> 288 <tbody className="divide-y divide- gray-100">288 <tbody className="divide-y divide-border"> 289 289 {getSortedExams().map((exam) => ( 290 <tr key={exam.id} className="hover:bg- gray-50 transition-colors duration-150">291 <td className="py-4 px-4 text-sm text- gray-900">{exam.id}</td>292 <td className="py-4 px-4 text-sm text- gray-900font-medium">{exam.subject}</td>293 <td className="py-4 px-4 text-sm text- gray-500">{exam.semester}</td>294 <td className="py-4 px-4 text-sm text- gray-500">{exam.credits}</td>295 <td className="py-4 px-4 text-sm text- gray-500">{exam.date}</td>290 <tr key={exam.id} className="hover:bg-accent/50 transition-colors duration-150"> 291 <td className="py-4 px-4 text-sm text-card-foreground">{exam.id}</td> 292 <td className="py-4 px-4 text-sm text-card-foreground font-medium">{exam.subject}</td> 293 <td className="py-4 px-4 text-sm text-muted-foreground">{exam.semester}</td> 294 <td className="py-4 px-4 text-sm text-muted-foreground">{exam.credits}</td> 295 <td className="py-4 px-4 text-sm text-muted-foreground">{exam.date}</td> 296 296 <td className="py-4 px-4"> 297 297 <span className={`inline-flex items-center px-2.5 py-1 rounded-md text-sm font-medium border ${getGradeColor(exam.grade)}`}> -
src/components/header.tsx
r50f2fb4 rba52069 45 45 46 46 return ( 47 <header className="bg- white shadow-sm border-b border-gray-200">47 <header className="bg-card shadow-sm border-b border-border"> 48 48 <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> 49 49 <div className="flex flex-col sm:flex-row sm:justify-between sm:items-center py-4 gap-4 sm:gap-0"> … … 72 72 {/* University Text */} 73 73 <div className="hidden sm:block"> 74 <div className="text- gray-900font-medium text-sm">74 <div className="text-card-foreground font-medium text-sm"> 75 75 {t('university')} 76 76 </div> 77 <div className="text- gray-700text-sm">77 <div className="text-muted-foreground text-sm"> 78 78 {t('faculty')} 79 79 </div> … … 88 88 <div className="flex items-center gap-2 sm:gap-3 w-full sm:w-auto justify-center sm:justify-end"> 89 89 {/* User Avatar */} 90 <div className="hidden sm:flex items-center justify-center w-10 h-10 bg- gray-800 text-whiterounded-full">90 <div className="hidden sm:flex items-center justify-center w-10 h-10 bg-primary text-primary-foreground rounded-full"> 91 91 <FontAwesomeIcon icon={faUser} className="text-sm" /> 92 92 </div> 93 93 {/* User Name */} 94 <div className="hidden sm:block text- gray-900font-medium">94 <div className="hidden sm:block text-card-foreground font-medium"> 95 95 {userName || '...'} 96 96 </div> 97 97 {/* Logout Button - more stylish and full width on mobile */} 98 98 <button 99 className="w-full sm:w-auto ml-0 sm:ml-2 px-4 py-2 border-2 border-primary text-primary bg- white rounded-lg font-semibold flex items-center justify-center gap-2 hover:bg-blue-50transition-all duration-200 shadow-sm"99 className="w-full sm:w-auto ml-0 sm:ml-2 px-4 py-2 border-2 border-primary text-primary bg-card rounded-lg font-semibold flex items-center justify-center gap-2 hover:bg-accent transition-all duration-200 shadow-sm" 100 100 onClick={handleLogout} 101 101 > -
src/components/navbar.tsx
r50f2fb4 rba52069 32 32 <> 33 33 {/* Desktop Navbar */} 34 <nav className="hidden md:flex flex-row gap-2 justify-evenly bg-primary text- whitep-7 rounded-xl my-5 text-xl">34 <nav className="hidden md:flex flex-row gap-2 justify-evenly bg-primary text-primary-foreground p-7 rounded-xl my-5 text-xl"> 35 35 {menuItems.map((item, index) => ( 36 36 <Link key={index} href={item.href}> 37 <div className="group flex flex-row items-center gap-2 px-3 py-2 rounded-lg cursor-pointer transition-all duration-300 hover:bg- white hover:bg-opacity-20 hover:scale-105 hover:shadow-lg hover:text-primary">37 <div className="group flex flex-row items-center gap-2 px-3 py-2 rounded-lg cursor-pointer transition-all duration-300 hover:bg-card hover:text-card-foreground hover:scale-105 hover:shadow-lg"> 38 38 <FontAwesomeIcon icon={item.icon} className="transition-transform duration-300 group-hover:rotate-12" /> 39 39 <span>{item.label}</span> … … 44 44 45 45 {/* Mobile Navbar */} 46 <nav className="md:hidden bg-primary text- whiterounded-xl my-5">46 <nav className="md:hidden bg-primary text-primary-foreground rounded-xl my-5"> 47 47 <div className="flex justify-between items-center p-4"> 48 48 {/* IKnow Logo/Text */} … … 55 55 <button 56 56 onClick={toggleMenu} 57 className="p-2 rounded-lg hover:bg- white hover:bg-opacity-20transition-colors duration-300"57 className="p-2 rounded-lg hover:bg-card hover:text-card-foreground transition-colors duration-300" 58 58 > 59 59 <FontAwesomeIcon … … 71 71 {menuItems.map((item, index) => ( 72 72 <Link key={index} href={item.href}> 73 <div className="group flex flex-row items-center gap-3 px-3 py-3 rounded-lg cursor-pointer transition-all duration-300 hover:bg- white hover:bg-opacity-20 hover:text-primary">73 <div className="group flex flex-row items-center gap-3 px-3 py-3 rounded-lg cursor-pointer transition-all duration-300 hover:bg-card hover:text-card-foreground"> 74 74 <FontAwesomeIcon icon={item.icon} className="transition-transform duration-300 group-hover:rotate-12" /> 75 75 <span className="text-lg">{item.label}</span> -
src/components/professor-navbar.tsx
r50f2fb4 rba52069 23 23 <> 24 24 {/* Desktop Navbar */} 25 <nav className="hidden md:flex flex-row gap-2 justify-evenly bg-primary text- whitep-7 rounded-xl my-5 text-xl">25 <nav className="hidden md:flex flex-row gap-2 justify-evenly bg-primary text-primary-foreground p-7 rounded-xl my-5 text-xl"> 26 26 {menuItems.map((item) => ( 27 27 <Link key={item.href} href={item.href}> 28 <div className="group flex flex-row items-center gap-2 px-3 py-2 rounded-lg cursor-pointer transition-all duration-300 hover:bg- white hover:bg-opacity-20 hover:scale-105 hover:shadow-lg hover:text-primary">28 <div className="group flex flex-row items-center gap-2 px-3 py-2 rounded-lg cursor-pointer transition-all duration-300 hover:bg-card hover:text-card-foreground hover:scale-105 hover:shadow-lg"> 29 29 <FontAwesomeIcon icon={item.icon} className="transition-transform duration-300 group-hover:rotate-12" /> 30 30 <span>{item.label}</span> … … 35 35 36 36 {/* Mobile Navbar */} 37 <nav className="md:hidden bg-primary text- whiterounded-xl my-5">37 <nav className="md:hidden bg-primary text-primary-foreground rounded-xl my-5"> 38 38 <div className="flex justify-between items-center p-4"> 39 39 <div className="flex items-center gap-2 text-xl font-bold"> … … 44 44 <button 45 45 onClick={toggleMenu} 46 className="p-2 rounded-lg hover:bg- white hover:bg-opacity-20transition-colors duration-300"46 className="p-2 rounded-lg hover:bg-card hover:text-card-foreground transition-colors duration-300" 47 47 aria-label="Toggle menu" 48 48 > … … 62 62 {menuItems.map((item) => ( 63 63 <Link key={item.href} href={item.href}> 64 <div className="group flex flex-row items-center gap-3 px-3 py-3 rounded-lg cursor-pointer transition-all duration-300 hover:bg- white hover:bg-opacity-20 hover:text-primary">64 <div className="group flex flex-row items-center gap-3 px-3 py-3 rounded-lg cursor-pointer transition-all duration-300 hover:bg-card hover:text-card-foreground"> 65 65 <FontAwesomeIcon 66 66 icon={item.icon}
Note:
See TracChangeset
for help on using the changeset viewer.
