feat: public split visibility, RLS recursion fixes, and consolidated tasting permission management
- Added public discovery section for active splits on the landing page - Refactored split detail page for guest support and login redirects - Extracted SplitCard component for reuse - Consolidated RLS policies for bottles and tastings to resolve permission errors - Added unified SQL consolidation script for RLS and naming fixes - Enhanced service logging for better database error diagnostics
This commit is contained in:
@@ -5,7 +5,10 @@ import { motion } from 'framer-motion';
|
||||
import { Lock, Eye, EyeOff, Loader2, CheckCircle, AlertCircle } from 'lucide-react';
|
||||
import { changePassword } from '@/services/profile-actions';
|
||||
|
||||
import { useI18n } from '@/i18n/I18nContext';
|
||||
|
||||
export default function PasswordChangeForm() {
|
||||
const { t } = useI18n();
|
||||
const [newPassword, setNewPassword] = useState('');
|
||||
const [confirmPassword, setConfirmPassword] = useState('');
|
||||
const [showPassword, setShowPassword] = useState(false);
|
||||
@@ -20,13 +23,13 @@ export default function PasswordChangeForm() {
|
||||
|
||||
if (newPassword !== confirmPassword) {
|
||||
setStatus('error');
|
||||
setError('Passwörter stimmen nicht überein');
|
||||
setError(t('settings.password.mismatch'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (newPassword.length < 6) {
|
||||
setStatus('error');
|
||||
setError('Passwort muss mindestens 6 Zeichen lang sein');
|
||||
setError(t('settings.password.tooShort'));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -43,7 +46,7 @@ export default function PasswordChangeForm() {
|
||||
setTimeout(() => setStatus('idle'), 3000);
|
||||
} else {
|
||||
setStatus('error');
|
||||
setError(result.error || 'Fehler beim Ändern');
|
||||
setError(result.error || t('common.error'));
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -58,14 +61,14 @@ export default function PasswordChangeForm() {
|
||||
>
|
||||
<h2 className="text-lg font-bold text-white mb-6 flex items-center gap-2">
|
||||
<Lock size={20} className="text-orange-500" />
|
||||
Passwort ändern
|
||||
{t('settings.password.title')}
|
||||
</h2>
|
||||
|
||||
<div className="space-y-4">
|
||||
{/* New Password */}
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-zinc-400 mb-2">
|
||||
Neues Passwort
|
||||
{t('settings.password.newPassword')}
|
||||
</label>
|
||||
<div className="relative">
|
||||
<input
|
||||
@@ -88,7 +91,7 @@ export default function PasswordChangeForm() {
|
||||
{/* Confirm Password */}
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-zinc-400 mb-2">
|
||||
Passwort bestätigen
|
||||
{t('settings.password.confirmPassword')}
|
||||
</label>
|
||||
<input
|
||||
type={showPassword ? 'text' : 'password'}
|
||||
@@ -107,12 +110,12 @@ export default function PasswordChangeForm() {
|
||||
{newPassword === confirmPassword ? (
|
||||
<>
|
||||
<CheckCircle size={12} />
|
||||
Passwörter stimmen überein
|
||||
{t('settings.password.match')}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<AlertCircle size={12} />
|
||||
Passwörter stimmen nicht überein
|
||||
{t('settings.password.mismatch')}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
@@ -122,7 +125,7 @@ export default function PasswordChangeForm() {
|
||||
{status === 'success' && (
|
||||
<div className="mt-4 p-3 bg-green-500/10 border border-green-500/20 rounded-xl flex items-center gap-2 text-green-500 text-sm">
|
||||
<CheckCircle size={16} />
|
||||
Passwort erfolgreich geändert!
|
||||
{t('settings.password.success')}
|
||||
</div>
|
||||
)}
|
||||
{status === 'error' && (
|
||||
@@ -141,12 +144,12 @@ export default function PasswordChangeForm() {
|
||||
{isPending ? (
|
||||
<>
|
||||
<Loader2 size={18} className="animate-spin" />
|
||||
Ändern...
|
||||
{t('common.loading')}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Lock size={18} />
|
||||
Passwort ändern
|
||||
{t('settings.password.change')}
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
|
||||
Reference in New Issue
Block a user