MIF_E31222881/resources/js/Pages/Profile/Profile.jsx

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>
);
}