153 lines
7.0 KiB
JavaScript
153 lines
7.0 KiB
JavaScript
import React, { useState, useEffect } from 'react';
|
|
import { useForm, usePage } from '@inertiajs/react';
|
|
import { useDispatch } from 'react-redux';
|
|
import { setPageTitle } from '@/Components/features/common/headerSlice';
|
|
import { Head } from '@inertiajs/react';
|
|
|
|
export default function ProfilePage() {
|
|
const { auth } = usePage().props;
|
|
const [preview, setPreview] = useState(null);
|
|
const id = auth.user.id
|
|
|
|
|
|
const { data, setData, post, processing, errors } = useForm({
|
|
nama: auth.user.nama || '',
|
|
alamat: auth.user.alamat || '',
|
|
no_telp: auth.user.no_telp || '',
|
|
jk: auth.user.jk || 'laki laki',
|
|
tanggal_lahir: auth.user.tanggal_lahir || '',
|
|
password: '',
|
|
foto: null
|
|
});
|
|
|
|
const dispatch = useDispatch();
|
|
|
|
useEffect(() => {
|
|
dispatch(setPageTitle("Profile Page"));
|
|
}, [dispatch]);
|
|
|
|
const handleSubmit = (e) => {
|
|
e.preventDefault();
|
|
post(route('profile.update', id));
|
|
};
|
|
|
|
const handlePhotoChange = (e) => {
|
|
const file = e.target.files[0];
|
|
if (file) {
|
|
const reader = new FileReader();
|
|
reader.onloadend = () => {
|
|
setPreview(reader.result);
|
|
};
|
|
reader.readAsDataURL(file);
|
|
setData('foto', file);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="w-full card max-w-4xl mx-auto bg-base-100 shadow-sm rounded-lg overflow-hidden">
|
|
<Head title="Profile Page" />
|
|
|
|
<div className="card-body">
|
|
<div className="px-6 py-4 flex items-center justify-between">
|
|
<div className="flex items-center">
|
|
<div className="relative h-16 w-16 rounded-full overflow-hidden mr-4 border border-gray-200 cursor-pointer group">
|
|
<label htmlFor="photo-upload" className="block relative h-16 w-16 rounded-full overflow-hidden border-4 border-transparent hover:border-blue-500 cursor-pointer">
|
|
<img
|
|
src={preview || auth.user.foto || "/fotoSantri/no-pic.png"}
|
|
alt="Profile"
|
|
className="h-full w-full object-cover transition duration-200"
|
|
/>
|
|
<div className="absolute inset-0 flex items-center justify-center bg-black opacity-0 hover:opacity-30 transition duration-200 rounded-full">
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
className="h-8 w-8 text-white"
|
|
fill="none"
|
|
viewBox="0 0 24 24"
|
|
stroke="currentColor"
|
|
>
|
|
<path
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
strokeWidth="2"
|
|
d="M12 4.5c-3.315 0-6 2.685-6 6s2.685 6 6 6 6-2.685 6-6-2.685-6-6-6zM12 10.5a2.25 2.25 0 100-4.5 2.25 2.25 0 000 4.5zm-6 5.25h12c.828 0 1.5.672 1.5 1.5v3c0 .828-.672 1.5-1.5 1.5H6c-.828 0-1.5-.672-1.5-1.5v-3c0-.828.672-1.5 1.5-1.5z"
|
|
/>
|
|
</svg>
|
|
</div>
|
|
<input
|
|
id="photo-upload"
|
|
type="file"
|
|
accept="image/*"
|
|
className="hidden"
|
|
onChange={handlePhotoChange}
|
|
/>
|
|
</label>
|
|
|
|
</div>
|
|
|
|
<div>
|
|
<h2 className="text-xl font-semibold">{auth.user.nama}</h2>
|
|
<p className="text-sm">{auth.user.level == 1 ? 'Admin' : ''}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<form onSubmit={handleSubmit} className="px-6 py-4" encType='multipart/form-data'>
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
<Input label="Nama Lengkap" name="nama" value={data.nama} onChange={setData} error={errors.nama} />
|
|
<Input label="Alamat" name="alamat" value={data.alamat} onChange={setData} error={errors.alamat} />
|
|
<Input label="No Telepon" name="no_telp" value={data.no_telp} onChange={setData} error={errors.no_telp} />
|
|
<Input label="Tanggal Lahir" name="tanggal_lahir" type="date" value={data.tanggal_lahir} onChange={setData} error={errors.tanggal_lahir} />
|
|
<Select label="Jenis Kelamin" name="jk" value={data.jk} onChange={setData} options={['laki laki', 'perempuan']} error={errors.jk} />
|
|
<Input label="Password" name="password" type="password" value={data.password} onChange={setData} error={errors.password} placeholder="Kosongkan jika tidak ingin mengganti password" />
|
|
</div>
|
|
<div className="mt-6 text-right">
|
|
<button
|
|
type='submit'
|
|
className="bg-blue-500 text-white px-4 py-2 rounded-md text-sm font-medium"
|
|
disabled={processing}
|
|
>
|
|
Simpan
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function Input({ label, name, value, onChange, type = 'text', error, placeholder = '' }) {
|
|
return (
|
|
<div>
|
|
<label className="block text-sm font-medium mb-1">{label}</label>
|
|
<input
|
|
type={type}
|
|
name={name}
|
|
value={value}
|
|
onChange={(e) => onChange(name, e.target.value)}
|
|
placeholder={placeholder}
|
|
className={`w-full px-4 py-2 bg-gray-50 border ${error ? 'border-red-500' : 'border-gray-200'} rounded-md focus:outline-none`}
|
|
/>
|
|
{error && <div className="text-red-500 text-sm mt-1">{error}</div>}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function Select({ label, name, value, onChange, options = [], error }) {
|
|
return (
|
|
<div>
|
|
<label className="block text-sm font-medium mb-1">{label}</label>
|
|
<select
|
|
name={name}
|
|
value={value}
|
|
onChange={(e) => onChange(name, e.target.value)}
|
|
className={`w-full px-4 py-2 bg-gray-50 border ${error ? 'border-red-500' : 'border-gray-200'} rounded-md focus:outline-none`}
|
|
>
|
|
{options.map((opt) => (
|
|
<option key={opt} value={opt}>{opt}</option>
|
|
))}
|
|
</select>
|
|
{error && <div className="text-red-500 text-sm mt-1">{error}</div>}
|
|
</div>
|
|
);
|
|
}
|