update HR dan Payroll
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
$csrfName=$this->security->get_csrf_token_name();$csrfHash=$this->security->get_csrf_hash();
|
||||
$initial=strtoupper(substr(trim((string)($user->nama?:$user->username)),0,1));
|
||||
$activeSessions=array_values(array_filter($sessions,function($row){return$row->status==='active';}));
|
||||
$historySessions=array_values(array_filter($sessions,function($row){return$row->status!=='active';}));
|
||||
$resultLabels=array('success'=>'Login berhasil','invalid_credentials'=>'Kredensial salah','device_limit'=>'Ditolak: batas perangkat');
|
||||
$resultClasses=array('success'=>'success','invalid_credentials'=>'danger','device_limit'=>'warning');
|
||||
$statusLabels=array('active'=>'Aktif','logged_out'=>'Logout','expired'=>'Kedaluwarsa','revoked'=>'Diakhiri');
|
||||
$statusClasses=array('active'=>'success','logged_out'=>'secondary','expired'=>'warning','revoked'=>'danger');
|
||||
function profileDateTime($value){return$value?date('d/m/Y H:i',strtotime($value)):'-';}
|
||||
?>
|
||||
<div class="profile-page">
|
||||
<section class="profile-hero"><div class="profile-identity"><div class="profile-avatar-large"><?php if(!empty($user->profile_photo)&&is_file(FCPATH.$user->profile_photo)):?><img src="<?=base_url($user->profile_photo)?>" alt="Foto profil"><?php else:?><?=html_escape($initial)?><?php endif?></div><div><span>AKUN PENGGUNA</span><h2 class="text-light"><?=html_escape($user->nama?:$user->username)?></h2><p>@<?=html_escape($user->username)?> • <?=html_escape($user->email?:'Email belum diatur')?></p></div></div><div class="profile-security-summary"><small>Keamanan Login</small><b><?=$active_count?> / <?=(int)($user->max_active_devices?:1)?> perangkat aktif</b><span>Durasi maksimum <?=(int)($user->session_duration_hours?:24)?> jam dari login pertama</span></div></section>
|
||||
|
||||
<?php foreach(array('success'=>'success','error'=>'danger')as$key=>$class)if($this->session->flashdata($key)):?><div class="alert alert-<?=$class?>"><?=html_escape($this->session->flashdata($key))?></div><?php endif?>
|
||||
<nav class="profile-tabs"><a class="<?=$profile_tab==='settings'?'active':''?>" href="<?=base_url('profile')?>"><i class="bi bi-person-gear"></i><span>Profil & Keamanan</span></a><a class="<?=$profile_tab==='devices'?'active':''?>" href="<?=base_url('profile?tab=devices')?>"><i class="bi bi-laptop"></i><span>Perangkat & Aktivitas</span><?php if($active_count):?><b><?=$active_count?></b><?php endif?></a></nav>
|
||||
|
||||
<?php if($profile_tab==='settings'):?>
|
||||
<div class="profile-grid">
|
||||
<section class="profile-card"><div class="profile-card-head"><div><h5>Informasi Profil</h5><p>Identitas yang tampil di dalam aplikasi.</p></div><i class="bi bi-person-vcard"></i></div><form method="post" enctype="multipart/form-data" action="<?=base_url('profile/update-profile')?>"><input type="hidden" name="<?=$csrfName?>" value="<?=$csrfHash?>"><div class="profile-photo-field"><div class="profile-avatar-preview"><?php if(!empty($user->profile_photo)&&is_file(FCPATH.$user->profile_photo)):?><img src="<?=base_url($user->profile_photo)?>" alt="Foto profil"><?php else:?><?=html_escape($initial)?><?php endif?></div><div><label class="form-label">Foto Profil</label><input class="form-control" type="file" name="profile_photo" accept="image/jpeg,image/png,image/webp"><small>JPG, PNG, atau WEBP; maksimal 2 MB.</small></div></div><div class="mb-3"><label class="form-label">Nama Lengkap</label><input class="form-control" name="nama" value="<?=html_escape($user->nama)?>" maxlength="255" required></div><div class="mb-3"><label class="form-label">Email</label><input class="form-control" type="email" name="email" value="<?=html_escape($user->email)?>" maxlength="150"></div><div class="mb-3"><label class="form-label">Username</label><input class="form-control" value="<?=html_escape($user->username)?>" disabled><small>Username dikelola oleh administrator.</small></div><button class="btn btn-primary"><i class="bi bi-check2-circle"></i> Simpan Profil</button></form></section>
|
||||
<div class="profile-stack">
|
||||
<section class="profile-card"><div class="profile-card-head"><div><h5>Pengaturan Session Login</h5><p>Batas waktu tetap dihitung sejak login pertama.</p></div><i class="bi bi-shield-check"></i></div><form method="post" action="<?=base_url('profile/update-security')?>"><input type="hidden" name="<?=$csrfName?>" value="<?=$csrfHash?>"><div class="row g-3"><div class="col-md-7"><label class="form-label">Durasi Maksimum Login</label><select class="form-select" name="session_duration_hours"><?php foreach(array(24=>'24 Jam',72=>'3 Hari',168=>'7 Hari')as$value=>$label):?><option value="<?=$value?>" <?=(int)$user->session_duration_hours===$value?'selected':''?>><?=$label?></option><?php endforeach?></select></div><div class="col-md-5"><label class="form-label">Batas Perangkat</label><input class="form-control" type="number" name="max_active_devices" min="1" max="10" value="<?=(int)($user->max_active_devices?:1)?>" required></div></div><div class="profile-notice"><i class="bi bi-info-circle"></i><span>Pengaturan baru berlaku saat login berikutnya. Rotasi ID session setiap 5 menit tidak memperpanjang batas ini.</span></div><button class="btn btn-primary"><i class="bi bi-save"></i> Simpan Pengaturan</button></form></section>
|
||||
<section class="profile-card"><div class="profile-card-head"><div><h5>Ganti Password</h5><p>Perangkat lain otomatis dikeluarkan setelah password diubah.</p></div><i class="bi bi-key"></i></div><form method="post" action="<?=base_url('profile/update-password')?>"><input type="hidden" name="<?=$csrfName?>" value="<?=$csrfHash?>"><div class="row g-3"><div class="col-12"><label class="form-label">Password Saat Ini</label><input class="form-control" type="password" name="current_password" autocomplete="current-password" required></div><div class="col-md-6"><label class="form-label">Password Baru</label><input class="form-control" type="password" name="new_password" autocomplete="new-password" minlength="8" required></div><div class="col-md-6"><label class="form-label">Konfirmasi Password</label><input class="form-control" type="password" name="confirm_password" autocomplete="new-password" minlength="8" required></div></div><small class="d-block mt-2">Minimal 8 karakter serta mengandung huruf dan angka.</small><button class="btn btn-outline-primary mt-3"><i class="bi bi-key"></i> Ubah Password</button></form></section>
|
||||
</div>
|
||||
</div>
|
||||
<?php else:?>
|
||||
<section class="profile-card mb-3"><div class="profile-card-head"><div><h5>Perangkat Aktif</h5><p>Session aktif menggunakan satu slot perangkat sampai logout, diakhiri, atau mencapai batas waktunya.</p></div><span class="profile-count"><?=count($activeSessions)?> aktif</span></div><div class="device-list"><?php foreach($activeSessions as$session):?><article class="device-row"><div class="device-icon"><i class="bi <?=$session->device_type==='Mobile'?'bi-phone':($session->device_type==='Tablet'?'bi-tablet':'bi-laptop')?>"></i></div><div class="device-main"><div><b><?=html_escape($session->browser.' di '.$session->platform)?></b><?php if($session->is_current):?><span class="badge bg-success">Perangkat ini</span><?php endif?></div><small><?=html_escape($session->device_type)?> • IP <?=html_escape($session->ip_address?:'-')?></small><div class="device-times"><span>Login <b><?=profileDateTime($session->login_at)?></b></span><span>Aktif terakhir <b><?=profileDateTime($session->last_seen_at)?></b></span><span>Berakhir <b><?=profileDateTime($session->expires_at)?></b></span></div><details><summary>Detail perangkat</summary><div class="user-agent"><?=html_escape($session->user_agent?:'-')?></div></details></div><form method="post" action="<?=base_url('profile/revoke-session/'.$session->id)?>" class="revoke-session-form"><input type="hidden" name="<?=$csrfName?>" value="<?=$csrfHash?>"><button class="btn btn-sm btn-outline-danger"><?=$session->is_current?'Logout perangkat ini':'Akhiri session'?></button></form></article><?php endforeach?><?php if(!$activeSessions):?><div class="profile-empty">Tidak ada perangkat aktif.</div><?php endif?></div></section>
|
||||
|
||||
<section class="profile-card mb-3"><div class="profile-card-head"><div><h5>Aktivitas & Percobaan Login</h5><p>Termasuk login berhasil, kredensial salah, dan permintaan yang ditolak karena batas perangkat.</p></div><i class="bi bi-clock-history"></i></div><div class="table-responsive"><table class="table align-middle profile-table"><thead><tr><th>Waktu</th><th>Perangkat</th><th>Alamat IP</th><th>Hasil</th><th>Keterangan</th></tr></thead><tbody><?php foreach($attempts as$attempt):?><tr><td><?=profileDateTime($attempt->attempted_at)?></td><td><b><?=html_escape($attempt->browser)?></b><small><?=html_escape($attempt->device_type)?> • <?=html_escape($attempt->platform)?></small></td><td><?=html_escape($attempt->ip_address?:'-')?></td><td><span class="badge bg-<?=$resultClasses[$attempt->result]??'secondary'?>"><?=html_escape($resultLabels[$attempt->result]??$attempt->result)?></span></td><td><?=html_escape($attempt->reason?:'-')?><?php if($attempt->result==='device_limit'):?><small><?=$attempt->active_session_count?> dari <?=$attempt->device_limit?> slot sedang aktif</small><?php endif?></td></tr><?php endforeach?><?php if(!$attempts):?><tr><td colspan="5" class="text-center text-muted py-4">Belum ada aktivitas login yang tercatat.</td></tr><?php endif?></tbody></table></div></section>
|
||||
|
||||
<?php if($historySessions):?><section class="profile-card"><div class="profile-card-head"><div><h5>Riwayat Session Terakhir</h5><p>Session yang telah logout, kedaluwarsa, atau diakhiri.</p></div></div><div class="table-responsive"><table class="table align-middle profile-table"><thead><tr><th>Perangkat</th><th>Login</th><th>Terakhir Aktif</th><th>Status</th><th>Alasan</th></tr></thead><tbody><?php foreach($historySessions as$session):?><tr><td><b><?=html_escape($session->browser.' di '.$session->platform)?></b><small><?=html_escape($session->device_type)?> • <?=html_escape($session->ip_address?:'-')?></small></td><td><?=profileDateTime($session->login_at)?></td><td><?=profileDateTime($session->last_seen_at)?></td><td><span class="badge bg-<?=$statusClasses[$session->status]??'secondary'?>"><?=html_escape($statusLabels[$session->status]??$session->status)?></span></td><td><?=html_escape($session->end_reason?:'-')?></td></tr><?php endforeach?></tbody></table></div></section><?php endif?>
|
||||
<?php endif?>
|
||||
</div>
|
||||
<script>document.querySelectorAll('.revoke-session-form').forEach(function(form){form.addEventListener('submit',function(event){event.preventDefault();var current=this.querySelector('button').textContent.indexOf('Logout')!==-1;AppAlert.confirm({title:current?'Logout perangkat ini?':'Akhiri session perangkat?',text:current?'Anda harus login kembali pada perangkat ini.':'Perangkat tersebut akan diminta login kembali.',icon:'warning'}).then(result=>{if(result.isConfirmed)form.submit()});});});</script>
|
||||
Reference in New Issue
Block a user