Update Settings.tsx
This commit is contained in:
@@ -6,7 +6,7 @@ import {
|
|||||||
Save, Building, Coins, Plus, Pencil, Trash2, X, CalendarCheck,
|
Save, Building, Coins, Plus, Pencil, Trash2, X, CalendarCheck,
|
||||||
AlertTriangle, User as UserIcon, Server, Bell, Clock, FileText,
|
AlertTriangle, User as UserIcon, Server, Bell, Clock, FileText,
|
||||||
Lock, Megaphone, CheckCircle2, Info, Hammer, Link as LinkIcon,
|
Lock, Megaphone, CheckCircle2, Info, Hammer, Link as LinkIcon,
|
||||||
Eye, Calendar, List, UserCog, Mail, Power, MapPin, CreditCard,
|
Eye, EyeOff, Calendar, List, UserCog, Mail, Power, MapPin, CreditCard,
|
||||||
ToggleLeft, ToggleRight, LayoutGrid, PieChart, Users, Send, Cloud, HardDrive, ChevronRight, Palette, Image as ImageIcon, Upload
|
ToggleLeft, ToggleRight, LayoutGrid, PieChart, Users, Send, Cloud, HardDrive, ChevronRight, Palette, Image as ImageIcon, Upload
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
|
|
||||||
@@ -51,6 +51,7 @@ export const SettingsPage: React.FC = () => {
|
|||||||
const [condoForm, setCondoForm] = useState<Partial<Condo>>({
|
const [condoForm, setCondoForm] = useState<Partial<Condo>>({
|
||||||
name: '', address: '', streetNumber: '', city: '', province: '', zipCode: '', notes: '', paypalClientId: '', defaultMonthlyQuota: 100, dueDay: 10
|
name: '', address: '', streetNumber: '', city: '', province: '', zipCode: '', notes: '', paypalClientId: '', defaultMonthlyQuota: 100, dueDay: 10
|
||||||
});
|
});
|
||||||
|
const [showPayPalKey, setShowPayPalKey] = useState(false); // State for PayPal input visibility
|
||||||
|
|
||||||
const [saving, setSaving] = useState(false);
|
const [saving, setSaving] = useState(false);
|
||||||
const [successMsg, setSuccessMsg] = useState('');
|
const [successMsg, setSuccessMsg] = useState('');
|
||||||
@@ -342,7 +343,26 @@ export const SettingsPage: React.FC = () => {
|
|||||||
<div><label className="text-xs font-bold text-slate-500 uppercase mb-2 block">Scadenza (Giorno)</label><input type="number" value={activeCondo.dueDay || 10} onChange={e => setActiveCondo({...activeCondo, dueDay: parseInt(e.target.value)})} className="w-full border border-slate-200 p-3 rounded-xl" /></div>
|
<div><label className="text-xs font-bold text-slate-500 uppercase mb-2 block">Scadenza (Giorno)</label><input type="number" value={activeCondo.dueDay || 10} onChange={e => setActiveCondo({...activeCondo, dueDay: parseInt(e.target.value)})} className="w-full border border-slate-200 p-3 rounded-xl" /></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div><label className="text-xs font-bold text-slate-500 uppercase mb-2 block">PayPal Client ID</label><input type="text" value={activeCondo.paypalClientId || ''} onChange={e => setActiveCondo({...activeCondo, paypalClientId: e.target.value})} className="w-full border border-slate-200 p-3 rounded-xl text-xs font-mono" /></div>
|
<div>
|
||||||
|
<label className="text-xs font-bold text-slate-500 uppercase mb-2 block">PayPal Client ID</label>
|
||||||
|
<div className="relative">
|
||||||
|
<input
|
||||||
|
type={showPayPalKey ? "text" : "password"}
|
||||||
|
value={activeCondo.paypalClientId || ''}
|
||||||
|
onChange={e => setActiveCondo({...activeCondo, paypalClientId: e.target.value})}
|
||||||
|
className="w-full border border-slate-200 p-3 rounded-xl text-xs font-mono pr-10"
|
||||||
|
placeholder="sandbox_..."
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => setShowPayPalKey(!showPayPalKey)}
|
||||||
|
className="absolute right-3 top-3 text-slate-400 hover:text-blue-600 transition-colors"
|
||||||
|
>
|
||||||
|
{showPayPalKey ? <EyeOff className="w-4 h-4" /> : <Eye className="w-4 h-4" />}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<p className="text-[10px] text-slate-400 mt-1">Necessario per abilitare i pagamenti online.</p>
|
||||||
|
</div>
|
||||||
<div className="pt-6 border-t flex justify-between items-center">
|
<div className="pt-6 border-t flex justify-between items-center">
|
||||||
<div className="flex-1">{successMsg && <span className="text-green-600 font-bold flex items-center gap-2"><CheckCircle2 className="w-5 h-5"/> {successMsg}</span>}</div>
|
<div className="flex-1">{successMsg && <span className="text-green-600 font-bold flex items-center gap-2"><CheckCircle2 className="w-5 h-5"/> {successMsg}</span>}</div>
|
||||||
<button type="submit" disabled={saving} className="bg-blue-600 text-white px-8 py-3 rounded-xl font-bold hover:bg-blue-700 shadow-lg flex items-center justify-center gap-2 disabled:opacity-50">
|
<button type="submit" disabled={saving} className="bg-blue-600 text-white px-8 py-3 rounded-xl font-bold hover:bg-blue-700 shadow-lg flex items-center justify-center gap-2 disabled:opacity-50">
|
||||||
@@ -443,12 +463,27 @@ export const SettingsPage: React.FC = () => {
|
|||||||
<div className="bg-white rounded-2xl shadow-sm border border-slate-200 p-8">
|
<div className="bg-white rounded-2xl shadow-sm border border-slate-200 p-8">
|
||||||
<div className="flex justify-between items-center mb-8"><h3 className="text-xl font-bold text-slate-800">Utenti</h3><button onClick={openAddUserModal} className="bg-blue-600 text-white px-4 py-2 rounded-xl font-bold flex items-center justify-center gap-2"><Plus className="w-4 h-4"/> Aggiungi</button></div>
|
<div className="flex justify-between items-center mb-8"><h3 className="text-xl font-bold text-slate-800">Utenti</h3><button onClick={openAddUserModal} className="bg-blue-600 text-white px-4 py-2 rounded-xl font-bold flex items-center justify-center gap-2"><Plus className="w-4 h-4"/> Aggiungi</button></div>
|
||||||
<div className="grid gap-4 md:grid-cols-2">
|
<div className="grid gap-4 md:grid-cols-2">
|
||||||
{users.map(u => (
|
{users.map(u => {
|
||||||
|
const isTargetAdmin = u.role === 'admin';
|
||||||
|
// Logic: PowerUsers cannot edit/delete Admins
|
||||||
|
const canManage = !(currentUser?.role === 'poweruser' && isTargetAdmin);
|
||||||
|
|
||||||
|
return (
|
||||||
<div key={u.id} className="p-5 border border-slate-100 rounded-2xl bg-slate-50 flex items-center justify-between">
|
<div key={u.id} className="p-5 border border-slate-100 rounded-2xl bg-slate-50 flex items-center justify-between">
|
||||||
<div><p className="font-bold text-slate-800">{u.name}</p><p className="text-xs text-slate-400">{u.email}</p><span className="text-[10px] uppercase font-bold bg-white px-2 py-0.5 rounded border border-slate-200 mt-1 inline-block">{u.role}</span></div>
|
<div><p className="font-bold text-slate-800">{u.name}</p><p className="text-xs text-slate-400">{u.email}</p><span className="text-[10px] uppercase font-bold bg-white px-2 py-0.5 rounded border border-slate-200 mt-1 inline-block">{u.role}</span></div>
|
||||||
<div className="flex gap-1"><button onClick={() => openEditUserModal(u)} className="p-2 text-blue-600 hover:bg-white rounded-lg"><Pencil className="w-4 h-4"/></button><button onClick={() => handleDeleteUser(u.id)} className="p-2 text-red-500 hover:bg-white rounded-lg"><Trash2 className="w-4 h-4"/></button></div>
|
<div className="flex gap-1">
|
||||||
|
{canManage ? (
|
||||||
|
<>
|
||||||
|
<button onClick={() => openEditUserModal(u)} className="p-2 text-blue-600 hover:bg-white rounded-lg"><Pencil className="w-4 h-4"/></button>
|
||||||
|
<button onClick={() => handleDeleteUser(u.id)} className="p-2 text-red-500 hover:bg-white rounded-lg"><Trash2 className="w-4 h-4"/></button>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<span className="text-[10px] text-slate-400 font-medium italic px-2 py-1">Protetto</span>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
))}
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
Reference in New Issue
Block a user