Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .Jules/palette.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## 2024-05-22 - [Inaccessible Custom File Uploads]
**Learning:** The app uses custom-styled `div` elements with `onClick` for file uploads, bypassing native keyboard accessibility and screen reader support.
**Action:** Always replace these with semantic `<button type="button">` or `<label>` elements wrapping the input, ensuring `type="button"` prevents form submission and adding `focus-visible` styles for keyboard users.
## 2024-05-23 - [Inconsistent Password Toggles]
**Learning:** Password visibility toggles are manually implemented across multiple files using icon buttons inside `Input` wrappers, consistently lacking `aria-label` and keyboard focus styles.
**Action:** When touching authentication forms, always add localized `aria-label` (e.g., 'Show password') and ensure `focus-visible` styles match the input's focus ring.
4 changes: 4 additions & 0 deletions src/contexts/LanguageContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ const translations: Record<Language, Record<string, string>> = {
'auth.welcomeBack': 'Welcome back',
'auth.loginSubtitle': 'Sign in to your account',
'auth.demoAccounts': 'Demo Accounts',
'auth.showPassword': 'Show password',
'auth.hidePassword': 'Hide password',

// New Auth translations
'error': 'Error',
Expand Down Expand Up @@ -381,6 +383,8 @@ const translations: Record<Language, Record<string, string>> = {
'auth.welcomeBack': '賲乇丨亘丕賸 亘毓賵丿鬲賰',
'auth.loginSubtitle': '爻噩賱 丿禺賵賱賰 廿賱賶 丨爻丕亘賰',
'auth.demoAccounts': '丨爻丕亘丕鬲 鬲噩乇賷亘賷丞',
'auth.showPassword': '廿馗賴丕乇 賰賱賲丞 丕賱賲乇賵乇',
'auth.hidePassword': '廿禺賮丕亍 賰賱賲丞 丕賱賲乇賵乇',

// New Auth translations
'error': '禺胤兀',
Expand Down
5 changes: 4 additions & 1 deletion src/pages/Auth.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@ export default function Auth() {
<button
type="button"
onClick={() => setShowPassword(!showPassword)}
className="absolute top-1/2 -translate-y-1/2 ltr:right-3 rtl:left-3 text-muted-foreground hover:text-foreground"
className="absolute top-1/2 -translate-y-1/2 ltr:right-3 rtl:left-3 text-muted-foreground hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary rounded-sm"
aria-label={showPassword ? t('auth.hidePassword') : t('auth.showPassword')}
>
{showPassword ? (
<EyeOff className="h-4 w-4" />
Expand All @@ -169,6 +170,7 @@ export default function Auth() {
size="icon"
className="rounded-full bg-white/50 backdrop-blur-sm hover:bg-white/80 text-black hover:text-black shadow-sm border border-gray-100 dark:bg-black/50 dark:hover:bg-black/80 dark:text-white dark:hover:text-white dark:border-gray-800"
title={t('theme.toggle')}
aria-label={t('theme.toggle')}
>
<Sun className="h-5 w-5 rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
<Moon className="absolute h-5 w-5 rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
Expand Down Expand Up @@ -196,6 +198,7 @@ export default function Auth() {
className="rounded-full bg-white/50 backdrop-blur-sm hover:bg-white/80 text-black hover:text-black shadow-sm border border-gray-100 dark:bg-black/50 dark:hover:bg-black/80 dark:text-white dark:hover:text-white dark:border-gray-800"
onClick={() => setLanguage(language === 'en' ? 'ar' : 'en')}
title={language === 'en' ? 'Switch to Arabic' : 'Switch to English'}
aria-label={language === 'en' ? 'Switch to Arabic' : 'Switch to English'}
>
<Languages className="h-5 w-5" />
</Button>
Expand Down
3 changes: 2 additions & 1 deletion src/pages/admin/AddUserForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,8 @@ export function AddUserForm({ onSuccess, defaultIsAshbal = false }: AddUserFormP
<button
type="button"
onClick={() => setShowPassword(!showPassword)}
className="absolute top-1/2 -translate-y-1/2 ltr:right-3 rtl:left-3 text-muted-foreground hover:text-foreground"
className="absolute top-1/2 -translate-y-1/2 ltr:right-3 rtl:left-3 text-muted-foreground hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary rounded-sm"
aria-label={showPassword ? t('auth.hidePassword') : t('auth.showPassword')}
>
{showPassword ? (
<EyeOff className="h-4 w-4" />
Expand Down
6 changes: 4 additions & 2 deletions src/pages/admin/UserManagement.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1091,7 +1091,8 @@ export default function UserManagement() {
<button
type="button"
onClick={() => setShowPassword(!showPassword)}
className="absolute top-1/2 -translate-y-1/2 ltr:right-3 rtl:left-3 text-muted-foreground hover:text-foreground"
className="absolute top-1/2 -translate-y-1/2 ltr:right-3 rtl:left-3 text-muted-foreground hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary rounded-sm"
aria-label={showPassword ? t('auth.hidePassword') : t('auth.showPassword')}
>
{showPassword ? (
<EyeOff className="h-4 w-4" />
Expand Down Expand Up @@ -1479,7 +1480,8 @@ export default function UserManagement() {
<button
type="button"
onClick={() => setShowPassword(!showPassword)}
className="absolute top-1/2 -translate-y-1/2 ltr:right-3 rtl:left-3 text-muted-foreground hover:text-foreground"
className="absolute top-1/2 -translate-y-1/2 ltr:right-3 rtl:left-3 text-muted-foreground hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary rounded-sm"
aria-label={showPassword ? t('auth.hidePassword') : t('auth.showPassword')}
>
{showPassword ? (
<EyeOff className="h-4 w-4" />
Expand Down