<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Buat Akun Baru</title>
<!-- Memuat Tailwind CSS -->
<script src="https://cdn.tailwindcss.com"></script>
<!-- Memuat Google Fonts: Inter -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
body {
font-family: 'Inter', sans-serif;
}
.toggle-checkbox:checked {
right: 0;
border-color: #4F46E5;
/* indigo-600 */
}
.toggle-checkbox:checked+.toggle-label {
background-color: #4F46E5;
/* indigo-600 */
}
</style>
</head>
<body class="bg-gray-100 flex items-center justify-center min-h-screen p-4">
<div class="w-full max-w-4xl mx-auto">
@session('error')
<div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative mb-4" role="alert">
<strong class="font-bold">Error!</strong>
<span class="block sm:inline">{{ session('error') }}</span>
</div>
@endsession
@if ($errors->any())
<div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative mb-4">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
</div>
<div class="w-full max-w-4xl bg-white rounded-2xl shadow-lg p-8">
<!-- Header -->
<div class="flex justify-between items-center mb-2">
<div class="flex items-center gap-3">
<a href="{{ route('login') }}" class="text-gray-600 hover:text-gray-900">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24"
stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7" />
</svg>
</a>
<h1 class="text-2xl font-bold text-gray-800">Buat Akun Baru</h1>
</div>
<span id="step-indicator" class="text-sm font-medium text-gray-500">Tahap 1 dari 3</span>
</div>
<!-- Progress Bar -->
<div class="w-full bg-gray-200 rounded-full h-2 mb-8">
<div id="progress-bar" class="bg-indigo-600 h-2 rounded-full transition-all duration-500"
style="width: 33.33%"></div>
</div>
<form id="registrationForm" action="{{ route('register') }}" method="POST" enctype="multipart/form-data">
@csrf
<!-- ======================= TAHAP 1: DATA DIRI & ALAMAT ======================= -->
<div id="step-1">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<!-- Foto KTP -->
<div>
<label for="uploadKTP" class="block text-sm font-medium text-gray-700">Foto KTP (maks 10MB)
<span class="text-red-500">*</span> <small class="text-xs text-red-500 mb-1">pastikan foto
ktp dapat dibaca</small></label>
<div class="mt-1 flex items-center">
<label
class="w-full flex justify-between items-center px-4 py-2 bg-white text-gray-700 rounded-lg border border-gray-300 cursor-pointer hover:bg-gray-50">
<span id="ktp-filename" class="text-sm">Upload KTP</span>
<span
class="px-4 py-1 text-sm font-semibold text-white bg-indigo-600 rounded-md hover:bg-indigo-700">Pilih</span>
<input type='file' class="hidden" id="uploadKTP" name="uploadKTP"
accept="image/jpeg, image/png" required />
</label>
@error('uploadKTP')
<span class="text-red-500 text-sm">{{ $message }}</span>
@enderror
</div>
</div>
<!-- NIK -->
<div> <label for="nik" class="block text-sm font-medium text-gray-700">NIK <span
class="text-red-500">*</span></label>
<input type="number" name="nik" id="nik"
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-hidden "
placeholder="Nomor Induk Kependudukan" required value="{{ old('nik') }}">
@error('nik')
<span class="text-red-500 text-sm">{{ $message }}</span>
@enderror
</div>
<!-- Nama Lengkap -->
<div> <label for="namaLengkap" class="block text-sm font-medium text-gray-700">Nama Lengkap <span
class="text-red-500">*</span></label>
<input type="text" name="namaLengkap" id="namaLengkap"
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-hidden "
placeholder="Nama Lengkap Sesuai KTP" required value="{{ old('namaLengkap') }}">
@error('namaLengkap')
<span class="text-red-500 text-sm">{{ $message }}</span>
@enderror
</div>
<!-- Alamat -->
<div> <label for="alamat" class="block text-sm font-medium text-gray-700">Alamat <span
class="text-red-500">*</span></label>
<input type="text" name="alamat" id="alamat"
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-hidden "
placeholder="Alamat Sesuai KTP" required value="{{ old('alamat') }}">
@error('alamat')
<span class="text-red-500 text-sm">{{ $message }}</span>
@enderror
</div>
<!-- Tanggal Lahir -->
<div> <label for="tanggalLahir" class="block text-sm font-medium text-gray-700">Tanggal Lahir <span
class="text-red-500">*</span></label>
<input type="date" name="tanggalLahir" id="tanggalLahir"
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-hidden "
required value="{{ old('tanggalLahir') }}">
@error('tanggalLahir')
<span class="text-red-500 text-sm">{{ $message }}</span>
@enderror
</div>
<!-- Tempat Lahir -->
<div> <label for="tempatLahir" class="block text-sm font-medium text-gray-700">Tempat Lahir <span
class="text-red-500">*</span></label>
<input type="text" name="tempatLahir" id="tempatLahir"
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-hidden "
placeholder="Kota Tempat Lahir" required value="{{ old('tempatLahir') }}">
@error('tempatLahir')
<span class="text-red-500 text-sm">{{ $message }}</span>
@enderror
</div>
<!-- Jenis Kelamin -->
<div>
<label for="jenisKelamin" class="block text-sm font-medium text-gray-700">Jenis Kelamin <span
class="text-red-500">*</span></label>
<select id="jenisKelamin" name="jenisKelamin" class="w-full px-4 py-3 border border-gray-300
rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-hidden " required>
<option value="" disabled selected>Pilih Jenis Kelamin</option>
<option value="Laki-laki" @selected(old('jenisKelamin') == "Laki-laki")>Laki-laki</option>
<option value="Perempuan" @selected(old('jenisKelamin') == "Perempuan")>Perempuan</option>
</select>
@error('jenisKelamin')
<span class="text-red-500 text-sm">{{ $message }}</span>
@enderror
</div>
<!-- Provinsi -->
<div>
<label for="provinsi_id" class="block text-sm font-medium text-gray-700">Provinsi <span
class="text-red-500">*</span></label>
<select id="provinsi_id" name="provinsi_id" class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500
focus:border-transparent outline-hidden " required onchange="handleInputChange(this)">
<option value="" disabled selected>Pilih Provinsi</option>
<!-- Opsi provinsi akan diisi secara dinamis dari API -->
</select>
@error('provinsi_id')
<span class="text-red-500 text-sm">{{ $message }}</span>
@enderror
</div>
<!-- Kabupaten/Kota -->
<div>
<label for="kabupaten_id" class="block text-sm font-medium text-gray-700">Kabupaten/Kota <span
class="text-red-500">*</span></label>
<select id="kabupaten_id" name="kabupaten_id" class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500
focus:border-transparent outline-hidden " required onchange="handleInputChange(this)">
<option value="" disabled selected>Pilih Kabupaten / Kota</option>
<!-- Opsi akan diisi setelah provinsi dipilih -->
</select>
@error('kabupaten_id')
<span class="text-red-500 text-sm">{{ $message }}</span>
@enderror
</div>
<!-- Kecamatan -->
<div>
<label for="kecamatan_id" class="block text-sm font-medium text-gray-700">Kecamatan <span
class="text-red-500">*</span></label>
<select id="kecamatan_id" name="kecamatan_id" class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500
focus:border-transparent outline-hidden " required onchange="handleInputChange(this)">
<option value="" disabled selected>Pilih Kecamatan</option>
<!-- Opsi akan diisi setelah kabupaten dipilih -->
</select>
@error('kecamatan_id')
<span class="text-red-500 text-sm">{{ $message }}</span>
@enderror
</div>
<!-- Kelurahan/Desa -->
<div>
<label for="kelurahan_id" class="block text-sm font-medium text-gray-700">Kelurahan/Desa <span
class="text-red-500">*</span></label>
<select id="kelurahan_id" name="kelurahan_id" class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500
focus:border-transparent outline-hidden " required>
<option value="" disabled selected>Pilih Kelurahan / Desa</option>
<!-- Opsi akan diisi setelah kecamatan dipilih -->
</select>
@error('kelurahan_id')
<span class="text-red-500 text-sm">{{ $message }}</span>
@enderror
</div>
<!-- Disabilitas -->
<div class="flex items-center justify-between mt-2 md:mt-8">
<span class="text-sm font-medium text-gray-700">Apakah anda penyandang disabilitas?</span>
<div
class="relative inline-block w-10 mr-2 align-middle select-none transition duration-200 ease-in">
<input type="checkbox" name="disabilitas" id="disabilitas" value="true"
class="toggle-checkbox absolute block w-6 h-6 rounded-full bg-white border-4 appearance-none cursor-pointer" />
<label for="disabilitas"
class="toggle-label block overflow-hidden h-6 rounded-full bg-gray-300 cursor-pointer"></label>
</div>
</div>
</div>
</div>
<!-- ======================= TAHAP 2: AKUN & KONTAK ======================= -->
<div id="step-2" class="hidden">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<!-- Email -->
<div class="md:col-span-2">
<label for="email" class="block text-sm font-medium text-gray-700">Email <span
class="text-red-500">*</span></label>
<input type="email" name="email" id="email"
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-hidden "
placeholder="[email protected]" required value="{{ old('email') }}">
@error('email')
<span class="text-red-500 text-sm">{{ $message }}</span>
@enderror
</div>
<!-- Password -->
<div> <label for="password" class="block text-sm font-medium text-gray-700">Password <span
class="text-red-500">*</span></label>
<input type="password" name="password" id="password"
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-hidden "
required>
@error('password')
<span class="text-red-500 text-sm">{{ $message }}</span>
@enderror
</div>
<!-- Konfirmasi Password -->
<div> <label for="password_confirmation" class="block text-sm font-medium text-gray-700">Konfirmasi
Password <span class="text-red-500">*</span></label>
<input type="password" name="password_confirmation" id="password_confirmation"
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-hidden "
required>
@error('password_confirmation')
<span class="text-red-500 text-sm">{{ $message }}</span>
@enderror
</div>
<!-- No HP -->
<div> <label for="phone" class="block text-sm font-medium text-gray-700">No. HP <span
class="text-red-500">*</span></label>
<input type="tel" name="phone" id="phone"
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-hidden "
placeholder="08123456789" required value="{{ old('phone') }}">
@error('phone')
<span class="text-red-500 text-sm">{{ $message }}</span>
@enderror
</div>
<!-- Foto Profil -->
<div>
<label for="photo" class="block text-sm font-medium text-gray-700">Foto Profil
(Opsional)</label>
<div class="mt-1 flex items-center">
<label
class="w-full flex justify-between items-center px-4 py-2 bg-white text-gray-700 rounded-lg border border-gray-300 cursor-pointer hover:bg-gray-50">
<span id="profile-photo-filename" class="text-sm">Upload Foto Profil</span>
<span
class="px-4 py-1 text-sm font-semibold text-white bg-indigo-600 rounded-md hover:bg-indigo-700">Pilih</span>
<input type='file' class="hidden" id="photo" name="photo"
accept="image/jpeg, image/png" />
</label>
</div>
</div>
</div>
</div>
<!-- ======================= TAHAP 3: PEKERJAAN ======================= -->
<div id="step-3" class="hidden">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<!-- Status Pekerjaan -->
<div class="md:col-span-2">
<label for="statusPekerjaan" class="block text-sm font-medium text-gray-700">Status
Pekerjaan
<span class="text-red-500">*</span></label>
<select id="statusPekerjaan" name="statusPekerjaan"
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-hidden "
required>
<option value="" disabled selected>Pilih Status Pekerjaan</option>
<option value="Bekerja" @selected(old('statusPekerjaan') == "Bekerja")>Bekerja</option>
<option value="Tidak Bekerja" @selected(old('statusPekerjaan') == "Tidak Bekerja")>Tidak
Bekerja</option>
<option value="Pelajar/Mahasiswa" @selected(old('statusPekerjaan') == "Pelajar/Mahasiswa")>Pelajar/Mahasiswa</option>
<option value="Lainnya" @selected(old('statusPekerjaan') == "Lainnya")>Lainnya</option>
</select>
@error('statusPekerjaan')
<span class="text-red-500 text-sm">{{ $message }}</span>
@enderror
</div>
<!-- Bidang Pekerjaan -->
<div id="bidangPekerjaan-wrapper" class="hidden">
<label for="bidangPekerjaan" class="block text-sm font-medium text-gray-700">Bidang</label>
<input type="text" name="bidangPekerjaan" id="bidangPekerjaan"
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-hidden "
placeholder="Contoh: Teknologi Informasi" value="{{ old('bidangPekerjaan') }}">
</div>
<!-- Tempat Bekerja -->
<div id="tempatBekerja-wrapper" class="hidden">
<label for="tempatBekerja" class="block text-sm font-medium text-gray-700">Tempat
Bekerja/Organisasi</label>
<input type="text" name="tempatBekerja" id="tempatBekerja"
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-hidden "
placeholder="Nama Perusahaan/Instansi" value="{{ old('tempatBekerja') }}">
</div>
<!-- Alamat Bekerja -->
<div id="alamatBekerja-wrapper" class="hidden md:col-span-2">
<label for="alamatBekerja" class="block text-sm font-medium text-gray-700">Alamat Tempat
Bekerja/Organisasi</label>
<textarea name="alamatBekerja" id="alamatBekerja" rows="3"
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-hidden "
placeholder="Alamat lengkap tempat bekerja">{{ old('alamatBekerja') }}</textarea>
</div>
</div>
</div>
<!-- Tombol Navigasi -->
<div class="mt-8 pt-5 border-t border-gray-200 flex justify-between items-center">
<button type="button" id="backBtn"
class="hidden px-6 py-2 text-sm font-medium text-gray-700 bg-gray-200 rounded-md hover:bg-gray-300">
Kembali
</button>
<!-- Spacer untuk mendorong tombol ke kanan jika tombol kembali tidak ada -->
<div id="spacer" class=""></div>
<button type="button" id="nextBtn"
class="px-6 py-2 text-sm font-medium text-white bg-indigo-600 rounded-md hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
Selanjutnya
</button>
<button type="submit" id="submitBtn"
class="hidden px-6 py-2 text-sm font-medium text-white bg-indigo-600 rounded-md hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
Daftar
</button>
</div>
</form>
</div>
<script>
document.addEventListener('DOMContentLoaded', function () {
// State
let currentStep = 1;
const totalSteps = 3;
// DOM Elements
const form = document.getElementById('registrationForm');
const steps = [document.getElementById('step-1'), document.getElementById('step-2'), document.getElementById('step-3')];
const backBtn = document.getElementById('backBtn');
const nextBtn = document.getElementById('nextBtn');
const submitBtn = document.getElementById('submitBtn');
const stepIndicator = document.getElementById('step-indicator');
const progressBar = document.getElementById('progress-bar');
const spacer = document.getElementById('spacer');
// File input UI handlers
const ktpInput = document.getElementById('uploadKTP');
const ktpFilename = document.getElementById('ktp-filename');
ktpInput.addEventListener('change', () => {
ktpFilename.textContent = ktpInput.files[0] ? ktpInput.files[0].name : 'Upload KTP';
});
const photoInput = document.getElementById('photo');
const photoFilename = document.getElementById('profile-photo-filename');
photoInput.addEventListener('change', () => {
photoFilename.textContent = photoInput.files[0] ? photoInput.files[0].name : 'Upload Foto Profil';
});
// Conditional fields for 'Pekerjaan'
const statusPekerjaan = document.getElementById('statusPekerjaan');
const pekerjaanWrappers = [
document.getElementById('bidangPekerjaan-wrapper'),
document.getElementById('tempatBekerja-wrapper'),
document.getElementById('alamatBekerja-wrapper')
];
statusPekerjaan.addEventListener('change', function () {
// if (this.value === 'Bekerja') {
// pekerjaanWrappers.forEach(el => el.classList.remove('hidden'));
// } else {
// pekerjaanWrappers.forEach(el => el.classList.add('hidden'));
// }
if (this.value === 'Tidak Bekerja') {
pekerjaanWrappers.forEach(el => el.classList.add('hidden'));
} else {
pekerjaanWrappers.forEach(el => el.classList.remove('hidden'));
}
});
// Functions
function updateUI() {
// Update step indicator text
stepIndicator.textContent = `Tahap ${currentStep} dari ${totalSteps}`;
// Update progress bar
progressBar.style.width = `${(currentStep / totalSteps) * 100}%`;
// Show/hide steps
steps.forEach((step, index) => {
if (index + 1 === currentStep) {
step.classList.remove('hidden');
} else {
step.classList.add('hidden');
}
});
// Update button visibility
backBtn.classList.toggle('hidden', currentStep === 1);
spacer.classList.toggle('hidden', currentStep !== 1);
nextBtn.classList.toggle('hidden', currentStep === totalSteps);
submitBtn.classList.toggle('hidden', currentStep !== totalSteps);
}
function validateStep(step) {
const inputs = steps[step - 1].querySelectorAll('input[required], select[required]');
let isValid = true;
for (const input of inputs) {
if (!input.value.trim()) {
input.classList.add('border-red-500');
isValid = false;
} else {
input.classList.remove('border-red-500');
}
//if input file add border-red to label
if (input.type === 'file' && input.files.length === 0) {
const label = input.parentElement;
label.classList.add('border-red-500');
isValid = false;
} else if (input.type === 'file') {
const label = input.parentElement;
label.classList.remove('border-red-500');
}
}
// Custom validation for password confirmation
if (step === 2) {
const password = document.getElementById('password');
const passwordConfirmation = document.getElementById('password_confirmation');
if (password.value !== passwordConfirmation.value) {
alert('Konfirmasi password tidak cocok!');
passwordConfirmation.classList.add('border-red-500');
isValid = false;
} else {
passwordConfirmation.classList.remove('border-red-500');
}
}
if (!isValid) {
alert('Harap isi semua kolom yang ditandai dengan *');
}
return isValid;
}
// Event Listeners
nextBtn.addEventListener('click', () => {
if (validateStep(currentStep)) {
currentStep++;
updateUI();
}
});
backBtn.addEventListener('click', () => {
currentStep--;
updateUI();
});
form.addEventListener('submit', function (e) {
if (!validateStep(currentStep)) {
e.preventDefault(); // Stop submission if validation fails
}
});
// Initial UI setup
updateUI();
});
const provinsiSelect = document.getElementById('provinsi_id');
fetch("{{ route('register.ajax-data', 'provinces') }}")
.then(res => res.json())
.then(data => {
data.forEach(provinsi => {
const option = document.createElement('option');
option.value = provinsi.id;
option.textContent = provinsi.name;
provinsiSelect.appendChild(option);
});
});
function handleInputChange(e) {
var name = e.name;
var value = e.value;
if (name === 'provinsi_id') {
const selectEl = document.getElementById('kabupaten_id');
fetch("{{ route('register.ajax-data', 'regencies') }}" + `?province_id=${value}`)
.then(res => res.json())
.then(data => {
data.forEach(provinsi => {
const option = document.createElement('option');
option.value = provinsi.id;
option.textContent = provinsi.name;
selectEl.appendChild(option);
});
});
} else if (name === 'kabupaten_id') {
const selectEl = document.getElementById('kecamatan_id');
fetch("{{ route('register.ajax-data', 'districts') }}" + `?regency_id=${value}`)
.then(res => res.json())
.then(data => {
data.forEach(provinsi => {
const option = document.createElement('option');
option.value = provinsi.id;
option.textContent = provinsi.name;
selectEl.appendChild(option);
});
});
} else if (name === 'kecamatan_id') {
const selectEl = document.getElementById('kelurahan_id');
fetch("{{ route('register.ajax-data', 'villages') }}" + `?district_id=${value}`)
.then(res => res.json())
.then(data => {
data.forEach(provinsi => {
const option = document.createElement('option');
option.value = provinsi.id;
option.textContent = provinsi.name;
selectEl.appendChild(option);
});
});
}
};
</script>
</body>
</html>
Anons79 File Manager Version 1.0, Coded By Anons79
Email: [email protected]