Initial commit
All checks were successful
Docker Build and Publish / build-and-push (push) Successful in 2m17s

This commit is contained in:
2026-01-11 18:55:03 -05:00
commit 493ea4688c
45 changed files with 7107 additions and 0 deletions

View File

@@ -0,0 +1,103 @@
import React, { useState, useEffect, useContext } from 'react';
import { pb } from '../../lib/pocketbase';
import { LanguageContext } from '../../contexts/LanguageContext';
const ProfileSettings = ({ user, onDelete }) => {
const { t } = useContext(LanguageContext);
const [isSupervisor, setIsSupervisor] = useState(user.is_supervisor || false);
const [supervisorId, setSupervisorId] = useState(user.supervisor || '');
const [availableSupervisors, setAvailableSupervisors] = useState([]);
const [loading, setLoading] = useState(false);
const [msg, setMsg] = useState('');
useEffect(() => {
const loadSupervisors = async () => {
try {
// Find all users who are supervisors
const result = await pb.collection('users').getList(1, 100, {
filter: 'is_supervisor = true',
});
// Exclude self
setAvailableSupervisors(result.items.filter(u => u.id !== user.id));
} catch (e) {
console.error("Error loading supervisors", e);
}
};
loadSupervisors();
}, [user.id]);
const handleSave = async (e) => {
e.preventDefault();
setLoading(true);
try {
await pb.collection('users').update(user.id, {
is_supervisor: isSupervisor,
supervisor: supervisorId
});
setMsg(t('profile.updated'));
// Refresh auth store might be needed or page reload
// pb.authStore.model is updated automatically on successful update?
// Actually it is usually good practice to refresh.
// But we will let the user navigate.
// To be safe, reload window or trigger parent refresh
window.location.reload();
} catch (err) {
console.error(err);
setMsg(t('profile.error'));
} finally {
setLoading(false);
}
};
return (
<div className="bg-white p-6 rounded-lg shadow-md mb-6">
<h3 className="text-lg font-semibold mb-4 text-gray-800">{t('profile.title')}</h3>
{msg && <div className="mb-4 p-2 bg-green-100 text-green-700 rounded block">{msg}</div>}
<form onSubmit={handleSave} className="space-y-4">
{/* Supervisor Toggle */}
<div className="flex items-center">
<input
type="checkbox"
id="is_supervisor"
checked={isSupervisor}
onChange={(e) => setIsSupervisor(e.target.checked)}
className="h-4 w-4 text-indigo-600 focus:ring-indigo-500 border-gray-300 rounded"
/>
<label htmlFor="is_supervisor" className="ml-2 block text-sm text-gray-900">
{t('profile.supervisor_check')}
</label>
</div>
{/* Supervisor Selection */}
<div>
<label className="block text-sm font-medium text-gray-700">{t('profile.my_supervisor')}</label>
<select
value={supervisorId}
onChange={(e) => setSupervisorId(e.target.value)}
className="mt-1 block w-full pl-3 pr-10 py-2 text-base border-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm rounded-md"
>
<option value="">{t('profile.select_supervisor')}</option>
{availableSupervisors.map(s => (
<option key={s.id} value={s.id}>
{s.name || s.email}
</option>
))}
</select>
</div>
<button
type="submit"
disabled={loading}
className="bg-indigo-600 text-white px-4 py-2 rounded-md hover:bg-indigo-700 disabled:opacity-50"
>
{loading ? t('profile.saving') : t('profile.save')}
</button>
</form>
</div>
);
};
export default ProfileSettings;