927 lines
54 KiB
HTML
927 lines
54 KiB
HTML
<!--
|
|
* © 2025-2026 Skoci Admin
|
|
* Designed and Developed by Abimanyu
|
|
* Contact : abimanyuag12@gmail.com
|
|
* All Rights Reserved
|
|
-->
|
|
|
|
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
<meta name="view-transition" content="same-origin">
|
|
<title>Skoci Admin | Basic Form</title>
|
|
<link rel="icon" type="image/x-icon" href="static/images/favicon.ico">
|
|
<!-- Bootstrap 5 -->
|
|
<link rel="stylesheet" href="static/vendor/bootstrap/bootstrap.min.css">
|
|
<link rel="stylesheet" href="static/css/style.css">
|
|
<link rel="stylesheet" href="static/vendor/bootstrap-icons/bootstrap-icons.css">
|
|
<!-- Icons -->
|
|
<link rel="stylesheet" href="static/vendor/tabler-icons/tabler-icons.css">
|
|
<link rel="stylesheet" href="static/vendor/micons/micons.css">
|
|
<link rel="stylesheet" href="static/vendor/mdi/materialdesignicons.min.css">
|
|
<link rel="stylesheet" href="static/vendor/remixicon/remixicon.css">
|
|
<link rel="stylesheet" href="static/vendor/coreui-icons/free.css">
|
|
<link rel="stylesheet" href="static/vendor/coreui-icons/brand.css">
|
|
<link rel="stylesheet" href="static/vendor/coreui-icons/flag.css">
|
|
<script src="static/vendor/jquery/jquery.min.js"></script>
|
|
</head>
|
|
|
|
<body>
|
|
<div id="bz-preloader">
|
|
<div class="bz-spinner"></div>
|
|
</div>
|
|
<!-- topbar-right -->
|
|
<div class="topbar-right">
|
|
<a href="index.html" class="text-decoration-none">
|
|
<div class="d-flex align-items-center gap-2">
|
|
<img src="static/images/logo.png" alt="logo-icon">
|
|
<div class="d-flex flex-column">
|
|
<h5 class="mb-0 fw-bold text-light text-uppercase">
|
|
Skoci
|
|
</h5>
|
|
</div>
|
|
</div>
|
|
</a>
|
|
<button id="toggleSidebarRight" class="btn btn-sm toggle-btn">
|
|
<i class="ri-arrow-left-s-line chevron"></i>
|
|
</button>
|
|
</div>
|
|
<!-- sidebar-right -->
|
|
<div class="sidebar-right">
|
|
<ul class="nav flex-column">
|
|
<li class="sidebar-title">
|
|
<span>Overview</span>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a href="index.html" class="nav-link" data-tooltip="Dashboard">
|
|
<i class="ri-apps-line"></i>
|
|
<span class="text-wrapper">
|
|
<span class="text-inner">Dashboard</span>
|
|
</span>
|
|
</a>
|
|
</li>
|
|
<li class="sidebar-title">
|
|
<span>Menu</span>
|
|
</li>
|
|
|
|
<li class="nav-item">
|
|
<a href="basic-form.html" class="nav-link active" data-tooltip="Form">
|
|
<i class="ri-layout-5-line"></i>
|
|
<span class="text-wrapper">
|
|
<span class="text-inner">Forms</span>
|
|
</span>
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link d-flex align-items-center"
|
|
data-bs-toggle="collapse"
|
|
href="#menuTables"
|
|
role="button"
|
|
aria-expanded="false"
|
|
aria-controls="menuTables">
|
|
<i class="ri-table-line"></i>
|
|
<span class="text-inner">Tables</span>
|
|
<i class="bi bi-chevron-right ms-auto"></i>
|
|
</a>
|
|
|
|
<div class="collapse" id="menuTables">
|
|
<ul class="nav flex-column">
|
|
<li class="nav-item">
|
|
<a href="table1.html" class="nav-link">
|
|
DataTables
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a href="table2.html" class="nav-link">
|
|
Bootstrap-Table
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link d-flex align-items-center"
|
|
data-bs-toggle="collapse"
|
|
href="#menuPages"
|
|
role="button"
|
|
aria-expanded="false"
|
|
aria-controls="menuPages">
|
|
<i class="cil-notes"></i>
|
|
<span class="text-inner">Pages</span>
|
|
<i class="bi bi-chevron-right ms-auto"></i>
|
|
</a>
|
|
|
|
<div class="collapse" id="menuPages">
|
|
<ul class="nav flex-column">
|
|
<li class="nav-item">
|
|
<a href="login.html" class="nav-link">
|
|
Login
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a href="404.html" class="nav-link">
|
|
404 Page
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a href="403.html" class="nav-link">
|
|
403 Page
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a href="blank-page.html" class="nav-link">
|
|
Blank Page
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</li>
|
|
<li class="sidebar-title">
|
|
<span>UI Elements</span>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a href="alert.html" class="nav-link" data-tooltip="Alert">
|
|
<i class="cil-bell"></i>
|
|
<span class="text-wrapper">
|
|
<span class="text-inner">Alerts</span>
|
|
</span>
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<!-- topbar-main -->
|
|
<div class="topbar-main">
|
|
<div class="d-flex align-items-center gap-3" style="height: 79px;">
|
|
<img class="d-lg-none" src="static/images/logo.png" alt="logo-icon">
|
|
<button id="mobileToogle" class="btn btn-topbar d-lg-none d-flex align-items-center justify-content-center">
|
|
<i class="ti ti-align-left"></i>
|
|
</button>
|
|
<div class="vr d-lg-none"></div>
|
|
<h5 class="fw-bold mb-0 text-uppercase fs-6 d-flex align-items-center">
|
|
Forms
|
|
</h5>
|
|
</div>
|
|
<div class="d-flex align-items-center gap-3">
|
|
<div class="position-relative search-form">
|
|
<input type="text" class="form-control" placeholder="Search for results...">
|
|
<i class="icon-search search-icon position-absolute top-50 end-0 translate-middle-y me-2"></i>
|
|
</div>
|
|
<div class="vr d-none d-lg-block"></div>
|
|
<!-- Cart -->
|
|
<button class="btn position-relative p-0 btn-topbar" type="button" data-bs-toggle="offcanvas" data-bs-target="#cartOffcanvas" aria-controls="messagesSidebar">
|
|
<i class="cil-cart"></i>
|
|
<span class="position-absolute translate-middle badge rounded-pill bg-danger d-flex align-items-center justify-content-center">
|
|
4
|
|
</span>
|
|
</button>
|
|
<!-- Notifikasi -->
|
|
<button class="btn position-relative p-0 btn-topbar border-0" type="button" data-bs-toggle="offcanvas" data-bs-target="#notificationOffcanvas" aria-controls="notificationOffcanvas">
|
|
<i class="cil-bell"></i>
|
|
<span class="position-absolute translate-middle badge rounded-pill bg-danger d-flex align-items-center justify-content-center">
|
|
2
|
|
</span>
|
|
</button>
|
|
<div class="vr"></div>
|
|
<!-- User Profile -->
|
|
<button
|
|
class="btn btn-link text-secondary text-decoration-none d-flex align-items-center gap-3 p-0"
|
|
type="button"
|
|
data-bs-toggle="offcanvas"
|
|
data-bs-target="#profileOffcanvas"
|
|
aria-controls="profileOffcanvas"
|
|
>
|
|
<img src="static/images/profile.png" alt="Profile Avatar" class="image-profile rounded-circle border border-2">
|
|
<div class="d-lg-flex align-items-center gap-1 d-none">
|
|
<div class="d-flex flex-column align-items-start lh-sm">
|
|
<div class="fw-bold" style="font-size: 1rem;">Admin</div>
|
|
<div class="text-muted small opacity-75">Superuser</div>
|
|
</div>
|
|
<!-- <i class="ti ti-chevron-down align-middle"></i> -->
|
|
</div>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<!-- topbar-secondary -->
|
|
<div class="topbar-secondary d-flex align-items-center justify-content-between">
|
|
<div class="d-flex align-items-center">
|
|
<a href="javascript:history.back()" class="btn-back d-none d-lg-block">
|
|
<i class="ri-arrow-left-double-line"></i>
|
|
</a>
|
|
<div class="vr mx-3 d-none d-lg-block"></div>
|
|
<h5 class="fw-medium mb-0 text-light">Basic Form</h5>
|
|
</div>
|
|
<nav>
|
|
<ul class="nav nav-pills d-none d-lg-flex overflow-auto flex-nowrap align-items-center">
|
|
<li class="nav-item"><a href="basic-form.html" class="nav-link active">Basic Form</a></li>
|
|
<li class="nav-item"><a href="advanced-form.html" class="nav-link">Advanced Form</a></li>
|
|
<div class="vr me-4 align-self-center bg-light" style="height: 18px; opacity: 0.4;"></div>
|
|
<li class="nav-item"><a href="#" class="nav-link" data-bs-toggle="modal" data-bs-target="#confirmModal"><i class="bi bi-info-circle"></i> Information</a></li>
|
|
</ul>
|
|
<div class="dropdown d-lg-none">
|
|
<button class="btn text-light border-0 p-2" type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
|
<i class="ri-menu-line fs-5"></i>
|
|
</button>
|
|
<ul class="dropdown-menu dropdown-menu-end shadow-sm bz-dropdown-menu">
|
|
<li>
|
|
<a class="dropdown-item active" href="basic-form.html">Basic Form</a>
|
|
</li>
|
|
<li>
|
|
<a class="dropdown-item" href="advanced-form.html">Advanced Form</a>
|
|
</li>
|
|
<li class="px-2"><hr class="dropdown-divider my-2 opacity-25 border-light"></li>
|
|
<li>
|
|
<a class="dropdown-item" href="#" data-bs-toggle="modal" data-bs-target="#confirmModal">
|
|
<i class="bi bi-info-circle"></i> Information
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</nav>
|
|
</div>
|
|
<!-- main-content -->
|
|
<div class="main-content">
|
|
<div class="container-fluid py-4">
|
|
<div class="row mt-2">
|
|
<div class="col-12">
|
|
<ul class="nav nav-tabs tab-style-1 d-sm-flex d-block" role="tablist">
|
|
<li class="nav-item" role="presentation">
|
|
<a class="nav-link active" data-bs-toggle="tab" data-bs-target="#tabs-1" aria-current="page" href="#tabs-1" aria-selected="true" role="tab">Tab Input 1</a>
|
|
</li>
|
|
<li class="nav-item" role="presentation">
|
|
<a class="nav-link" data-bs-toggle="tab" data-bs-target="#tabs-2" href="#tabs-2" aria-selected="tabs-2" tabindex="-1" role="tab">Tab Input 2</a>
|
|
</li>
|
|
</ul>
|
|
<div class="tab-content">
|
|
<div class="tab-pane fade show active" id="tabs-1" role="tabpanel">
|
|
<div class="card shadow-lg border-0">
|
|
<form method="POST" enctype="multipart/form-data">
|
|
<div class="card-body p-5">
|
|
<div class="d-flex justify-content-between align-items-center border-bottom pb-2 mb-4">
|
|
<h6 class="mb-0">
|
|
Input 1
|
|
</h6>
|
|
<div class="dropdown">
|
|
<button class="btn btn-bz-size bz-btn-outline-primary dropdown-toggle" type="button" id="excelDropdown" data-bs-toggle="dropdown" aria-expanded="false">
|
|
Bulk Import
|
|
</button>
|
|
<div class="dropdown-menu" aria-labelledby="excelDropdown">
|
|
<a class="dropdown-item" href="#" target="_blank">Download Template</a>
|
|
<a class="dropdown-item" href="#" data-bs-toggle="modal" data-bs-target="#uploadModal">Import Data</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row g-4">
|
|
<div class="col-12 col-md-6">
|
|
<label for="id_general_input" class="form-label">
|
|
Input Label
|
|
</label>
|
|
<input type="text"
|
|
name="general_input"
|
|
value="DELL-5430-KYBD"
|
|
placeholder="Enter information..."
|
|
class="form-control is-invalid"
|
|
autocomplete="off"
|
|
required
|
|
aria-describedby="id_input_help id_input_error"
|
|
id="id_general_input">
|
|
|
|
<div id="id_input_help" class="form-text ms-1 text-muted">
|
|
This field is required. Please provide a unique value.
|
|
</div>
|
|
|
|
<div id="id_input_error" class="form-text text-danger ms-1">
|
|
An entry with this value already exists in the system.
|
|
</div>
|
|
</div>
|
|
<div class="col-12 col-md-6">
|
|
<div class="mb-3">
|
|
<label for="id_generic_text" class="form-label">
|
|
Input Label
|
|
</label>
|
|
|
|
<input type="text"
|
|
name="generic_text"
|
|
value="Internal Keyboard US-English"
|
|
placeholder="Enter value here..."
|
|
class="form-control"
|
|
autocomplete="off"
|
|
id="id_generic_text"
|
|
aria-describedby="generic_text_help">
|
|
|
|
<div id="generic_text_help" class="form-text ms-1">
|
|
Optional. Provide the necessary information for this field.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-12 col-md-6">
|
|
<div class="mb-3">
|
|
<label for="id_general_select" class="form-label">
|
|
Select Option
|
|
</label>
|
|
<select name="general_select" class="form-select" autocomplete="off" id="id_general_select" aria-describedby="select_help">
|
|
<option value="" disabled selected>-- Select an option --</option>
|
|
<option value="electronics">Electronics</option>
|
|
<option value="accessories">Accessories</option>
|
|
<option value="office-supplies">Office Supplies</option>
|
|
<option value="other">Other</option>
|
|
</select>
|
|
<div id="select_help" class="form-text ms-1">
|
|
Please select one option from the list.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-12 col-md-6">
|
|
<label for="id_generic_input" class="form-label">
|
|
Input Value
|
|
</label>
|
|
<input type="number"
|
|
name="generic_numeric_field"
|
|
value="1"
|
|
class="form-control numeric-input"
|
|
autocomplete="off"
|
|
id="id_generic_input"
|
|
aria-describedby="generic_help_text">
|
|
|
|
<div id="generic_help_text" class="form-text ms-1">
|
|
Enter a numeric value if applicable.
|
|
</div>
|
|
</div>
|
|
<div class="col-12 col-md-6">
|
|
<label for="id_is_active" class="form-label">
|
|
Option Status
|
|
</label>
|
|
<div class="form-check mt-1">
|
|
<input type="checkbox"
|
|
name="is_active"
|
|
class="form-check-input"
|
|
id="id_is_active"
|
|
checked="">
|
|
<label class="form-check-label" for="id_is_active">
|
|
Enable this feature
|
|
</label>
|
|
</div>
|
|
<div id="status_help" class="form-text ms-1">
|
|
Toggle to set the current availability of this record.
|
|
</div>
|
|
</div>
|
|
<div class="col-12 col-md-6">
|
|
<label for="id_general_textarea" class="form-label">
|
|
Additional Information
|
|
</label>
|
|
<textarea
|
|
class="form-control"
|
|
name="general_notes"
|
|
id="id_general_textarea"
|
|
rows="4"
|
|
placeholder="Provide additional details or notes here..."
|
|
aria-describedby="textarea_help"
|
|
></textarea>
|
|
|
|
<div id="textarea_help" class="form-text ms-1">
|
|
You may include any relevant notes or details in this section.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<hr class="my-5">
|
|
<div class="d-flex justify-content-end">
|
|
<button onclick="history.back()" class="btn bz-btn-outline-primary btn-bz-size me-2">Cancel</button>
|
|
<button class="btn bz-btn-primary btn-bz-size" type="submit">Submit</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<div class="tab-pane fade" id="tabs-2" role="tabpanel">
|
|
<div class="card shadow-lg border-0">
|
|
<form method="GET">
|
|
<div class="card-body p-5">
|
|
<div class="d-flex justify-content-between align-items-center border-bottom pb-2 mb-4">
|
|
<h6 class="mb-0">
|
|
Input 2
|
|
</h6>
|
|
</div>
|
|
<div class="row g-4">
|
|
<div class="col-12 col-md-6">
|
|
<label for="id_image" class="form-label">
|
|
Media Upload
|
|
</label>
|
|
<div>
|
|
<img id="imagePreview" src="static/images/placeholder.jpg" alt="Preview" class="mb-3 w-50 rounded border">
|
|
</div>
|
|
<input type="file"
|
|
name="media_file"
|
|
class="form-control"
|
|
accept="image/*"
|
|
autocomplete="off"
|
|
id="id_image"
|
|
aria-describedby="media_help">
|
|
|
|
<div id="media_help" class="form-text ms-1">
|
|
Accepted formats: JPG, PNG, or WEBP. (Maximum file size: 5MB).
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<hr class="my-5">
|
|
<div class="d-flex justify-content-end">
|
|
<button onclick="history.back()" class="btn bz-btn-outline-primary btn-bz-size me-2">Cancel</button>
|
|
<button class="btn bz-btn-primary btn-bz-size" type="submit">Submit</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- offcanvas -->
|
|
<div class="offcanvas offcanvas-end" tabindex="-1" id="cartOffcanvas" aria-labelledby="cartOffcanvas">
|
|
<div class="offcanvas-header border-bottom">
|
|
<div class="d-flex align-items-center w-100">
|
|
<div class="flex-grow-1">
|
|
<p class="offcanvas-title mb-0 fw-bold" id="cartOffcanvasLabel">
|
|
Carts
|
|
</p>
|
|
<div class="fsmall mb-0">You have 4 item in your cart</div>
|
|
</div>
|
|
<div class="d-flex align-items-center">
|
|
<button type="button" class="btn-close btn-close-white small" data-bs-dismiss="offcanvas" aria-label="Close"></button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="offcanvas-body p-0">
|
|
<div id="cartContainer">
|
|
<div class="list-group list-group-flush">
|
|
<a href="#" class="list-group-item list-group-item-action border-bottom py-2 px-3">
|
|
<div class="d-flex align-items-start">
|
|
<div class="me-3">
|
|
<div class="rounded-circle bg-primary bg-opacity-10 text-primary d-flex align-items-center justify-content-center"
|
|
style="width: 36px; height: 36px;">
|
|
<i class="bi bi-cart"></i>
|
|
</div>
|
|
</div>
|
|
<div class="flex-grow-1">
|
|
<div class="d-flex justify-content-between align-items-start">
|
|
<div>
|
|
<div class="fw-bold text-dark mb-1">DELL-5430-KYBD</div>
|
|
<div class="text-muted small mb-2">Internal Keyboard US-English</div>
|
|
</div>
|
|
<small class="text-muted text-nowrap ms-3 d-flex align-items-center">
|
|
<i class="ri-time-line me-1"></i>2 minutes ago
|
|
</small>
|
|
</div>
|
|
<div class="text-muted small">Qty: 2 unit(s)</div>
|
|
</div>
|
|
</div>
|
|
</a>
|
|
<a href="#" class="list-group-item list-group-item-action border-bottom py-2 px-3">
|
|
<div class="d-flex align-items-start">
|
|
<div class="me-3">
|
|
<div class="rounded-circle bg-primary bg-opacity-10 text-primary d-flex align-items-center justify-content-center"
|
|
style="width: 36px; height: 36px;">
|
|
<i class="bi bi-cart"></i>
|
|
</div>
|
|
</div>
|
|
<div class="flex-grow-1">
|
|
<div class="d-flex justify-content-between align-items-start">
|
|
<div>
|
|
<div class="fw-bold text-dark mb-1">BATT-54WH-RY</div>
|
|
<div class="text-muted small mb-2">Battery 4-Cell 54Wh Long Life</div>
|
|
</div>
|
|
<small class="text-muted text-nowrap ms-3 d-flex align-items-center">
|
|
<i class="ri-time-line me-1"></i>15 minutes ago
|
|
</small>
|
|
</div>
|
|
<div class="text-muted small">Qty: 1 unit(s)</div>
|
|
</div>
|
|
</div>
|
|
</a>
|
|
<a href="#" class="list-group-item list-group-item-action border-bottom py-2 px-3">
|
|
<div class="d-flex align-items-start">
|
|
<div class="me-3">
|
|
<div class="rounded-circle bg-primary bg-opacity-10 text-primary d-flex align-items-center justify-content-center"
|
|
style="width: 36px; height: 36px;">
|
|
<i class="bi bi-cart"></i>
|
|
</div>
|
|
</div>
|
|
<div class="flex-grow-1">
|
|
<div class="d-flex justify-content-between align-items-start">
|
|
<div>
|
|
<div class="fw-bold text-dark mb-1">SSD-NVME-512</div>
|
|
<div class="text-muted small mb-2">512GB NVMe M.2 2280 Gen4</div>
|
|
</div>
|
|
<small class="text-muted text-nowrap ms-3 d-flex align-items-center">
|
|
<i class="ri-time-line me-1"></i>1 hours ago
|
|
</small>
|
|
</div>
|
|
<div class="text-muted small">Qty: 5 unit(s)</div>
|
|
</div>
|
|
</div>
|
|
</a>
|
|
<a href="#" class="list-group-item list-group-item-action border-bottom py-2 px-3">
|
|
<div class="d-flex align-items-start">
|
|
<div class="me-3">
|
|
<div class="rounded-circle bg-primary bg-opacity-10 text-primary d-flex align-items-center justify-content-center"
|
|
style="width: 36px; height: 36px;">
|
|
<i class="bi bi-cart"></i>
|
|
</div>
|
|
</div>
|
|
<div class="flex-grow-1">
|
|
<div class="d-flex justify-content-between align-items-start">
|
|
<div>
|
|
<p class="fw-bold text-dark mb-1">MEM-DDR4-16G</p>
|
|
<div class="text-muted small mb-2">16GB DDR4 3200MHz SODIMM</div>
|
|
</div>
|
|
<small class="text-muted text-nowrap ms-3 d-flex align-items-center">
|
|
<i class="ri-time-line me-1"></i>2 hours ago
|
|
</small>
|
|
</div>
|
|
<div class="text-muted small">Qty: 3 unit(s)</div>
|
|
</div>
|
|
</div>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="offcanvas offcanvas-end" tabindex="-1" id="notificationOffcanvas" aria-labelledby="notificationOffcanvasLabel">
|
|
<div class="offcanvas-header border-bottom">
|
|
<div class="d-flex align-items-center w-100">
|
|
<div class="flex-grow-1">
|
|
<p class="offcanvas-title mb-0 fw-bold" id="notificationOffcanvasLabel">
|
|
Notifications
|
|
</p>
|
|
<div class="fsmall mb-0">You have 2 new notifications</div>
|
|
</div>
|
|
<div class="d-flex align-items-center">
|
|
<button type="button" class="btn-close btn-close-white small" data-bs-dismiss="offcanvas" aria-label="Close"></button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="offcanvas-body p-0">
|
|
<div id="notificationContainer">
|
|
<div class="sticky-top bg-light">
|
|
<div class="d-flex justify-content-between align-items-center px-2 border">
|
|
<div class="d-flex align-items-center ps-2">
|
|
<div class="form-check d-flex align-items-center m-0 p-0">
|
|
<input class="form-check-input m-0" type="checkbox" id="selectAll">
|
|
<label class="form-check-label ms-3" for="selectAll">Select All</label>
|
|
</div>
|
|
</div>
|
|
<div class="d-flex align-items-center">
|
|
<div class="btn-group" role="group">
|
|
<button type="button" onclick="handleBulkAction('mark_read')" id="btnBulkRead" class="btn btn-sm btn-link text-secondary text-decoration-none">
|
|
<i class="ri-mail-open-line"></i><span> Mark Read</span>
|
|
</button>
|
|
<div class="vr mx-2 align-self-center" style="height: 16px; opacity: 0.2;"></div>
|
|
<button type="button" onclick="handleBulkAction('delete')" id="btnBulkDelete" class="btn btn-sm btn-link text-danger text-decoration-none">
|
|
<i class="ri-delete-bin-line"></i><span> Delete</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="list-group list-group-flush">
|
|
<!-- Item 1 -->
|
|
<div class="list-group-item p-0 border-bottom bg-offcanvas-body text-dark fw-semibold">
|
|
<div class="d-flex align-items-start py-2 px-3">
|
|
<div class="pe-3 pt-1">
|
|
<input class="form-check-input notif-checkbox" type="checkbox">
|
|
</div>
|
|
<a href="#" class="text-decoration-none text-dark d-flex justify-content-between align-items-start flex-grow-1 gap-3">
|
|
<div>
|
|
<p class="mb-0 small">
|
|
Your Order Has Been Shipped
|
|
</p>
|
|
<span class="text-muted small">
|
|
Order #DO-123456 has shipped to your delivery address
|
|
</span>
|
|
</div>
|
|
<div class="text-muted small text-nowrap d-flex align-items-center pt-1">
|
|
<i class="ri-time-line me-1"></i>
|
|
2 hours ago
|
|
</div>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Item 2 -->
|
|
<div class="list-group-item p-0 border-bottom bg-offcanvas-body text-dark fw-semibold">
|
|
<div class="d-flex align-items-start py-2 px-3">
|
|
<!-- Checkbox -->
|
|
<div class="pe-3 pt-1">
|
|
<input class="form-check-input notif-checkbox" type="checkbox">
|
|
</div>
|
|
<!-- Content -->
|
|
<a href="#" class="text-decoration-none text-dark d-flex justify-content-between align-items-start flex-grow-1 gap-3">
|
|
<!-- Left -->
|
|
<div>
|
|
<p class="mb-0 small">
|
|
Payment Received
|
|
</p>
|
|
<span class="text-muted small">
|
|
Invoice #INV-202401 has been paid successfully
|
|
</span>
|
|
</div>
|
|
<!-- Time -->
|
|
<div class="text-muted small text-nowrap d-flex align-items-center pt-1">
|
|
<i class="ri-time-line me-1"></i>
|
|
5 hours ago
|
|
</div>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Item 3 -->
|
|
<div class="list-group-item p-0 border-bottom text-dark fw-normal">
|
|
<div class="d-flex align-items-start py-2 px-3">
|
|
<!-- Checkbox -->
|
|
<div class="pe-3 pt-1">
|
|
<input class="form-check-input notif-checkbox" type="checkbox">
|
|
</div>
|
|
<!-- Content -->
|
|
<a href="#" class="text-decoration-none text-dark d-flex justify-content-between align-items-start flex-grow-1 gap-3">
|
|
<!-- Left -->
|
|
<div>
|
|
<p class="mb-0 small">
|
|
New Login Detected
|
|
</p>
|
|
<span class="text-muted small">
|
|
Jakarta, ID • Chrome on Ubuntu
|
|
</span>
|
|
</div>
|
|
<!-- Time -->
|
|
<div class="text-muted small text-nowrap d-flex align-items-center pt-1">
|
|
<i class="ri-time-line me-1"></i>
|
|
Yesterday
|
|
</div>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Item 4 -->
|
|
<div class="list-group-item p-0 border-bottom text-dark fw-normal">
|
|
<div class="d-flex align-items-start py-2 px-3">
|
|
<!-- Checkbox -->
|
|
<div class="pe-3 pt-1">
|
|
<input class="form-check-input notif-checkbox" type="checkbox">
|
|
</div>
|
|
<!-- Content -->
|
|
<a href="#" class="text-decoration-none text-dark d-flex justify-content-between align-items-start flex-grow-1 gap-3">
|
|
<!-- Left -->
|
|
<div>
|
|
<p class="mb-0 small">
|
|
Stock Opname in Progress
|
|
</p>
|
|
<span class="text-muted small">
|
|
Reference: #SO-12-2025 (Warehouse B)
|
|
</span>
|
|
</div>
|
|
<!-- Time -->
|
|
<div class="text-muted small text-nowrap d-flex align-items-center pt-1">
|
|
<i class="ri-time-line me-1"></i>
|
|
4 days ago
|
|
</div>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Item 5 -->
|
|
<div class="list-group-item p-0 border-bottom text-dark fw-normal">
|
|
<div class="d-flex align-items-start py-2 px-3">
|
|
<!-- Checkbox -->
|
|
<div class="pe-3 pt-1">
|
|
<input class="form-check-input notif-checkbox" type="checkbox">
|
|
</div>
|
|
<!-- Content -->
|
|
<a href="#" class="text-decoration-none text-dark d-flex justify-content-between align-items-start flex-grow-1 gap-3">
|
|
<!-- Left -->
|
|
<div>
|
|
<p class="mb-0 small">
|
|
System Test Completed
|
|
</p>
|
|
<span class="text-muted small">
|
|
Reference: #TEST-DEBUG-LOG
|
|
</span>
|
|
</div>
|
|
|
|
<!-- Time -->
|
|
<div class="text-muted small text-nowrap d-flex align-items-center pt-1">
|
|
<i class="ri-time-line me-1"></i>
|
|
6 days ago
|
|
</div>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="offcanvas offcanvas-end" tabindex="-1" id="profileOffcanvas" aria-labelledby="profileOffcanvasLabel">
|
|
<div class="offcanvas-header border-bottom">
|
|
<div class="d-flex align-items-center w-100">
|
|
<div class="flex-grow-1">
|
|
<p class="offcanvas-title mb-0 fw-bold" id="profileOffcanvasLabel">
|
|
Your Account
|
|
</p>
|
|
<div class="fsmall mb-0">Last sign-in: 02/01/2025-2026 17:36</div>
|
|
</div>
|
|
<button type="button" class="btn-close btn-close-white small" data-bs-dismiss="offcanvas" aria-label="Close"></button>
|
|
</div>
|
|
</div>
|
|
<div class="offcanvas-body p-0">
|
|
<div class="p-4 text-center text-account-dropdown">
|
|
<div class="position-relative d-inline-block mx-auto">
|
|
<div class="profile-img-container">
|
|
<img src="static/images/profile.png" class="img img-thumbnail rounded-circle w-25" alt="Profile Avatar">
|
|
</div>
|
|
</div>
|
|
<div class="fw-bold mt-3 mb-2 opacity-75" style="font-size: 1rem;">Admin</div>
|
|
<div class="text-muted fsmall opacity-75">Superuser</div>
|
|
<div class="text-muted fsmall opacity-75">admin@mail.com</div>
|
|
<div class="mt-3 text-center">
|
|
<button type="button" class="btn btn-danger btn-bz-size" onclick="location.href='login.html'">
|
|
<i class="ri-logout-box-r-line"></i> Sign Out
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- Copyright -->
|
|
<div class="offcanvas-footer p-4 bg-light">
|
|
<div class="text-center text-muted fsmall">
|
|
<p class="fw-semibold text-dark mb-2">
|
|
© 2025-2026 Skoci Admin<br>All rights reserved.
|
|
</p>
|
|
<p class="mb-2">
|
|
<a href="https://github.com/abeemanew/skoci-admin" target="_blank" class="text-decoration-none text-muted">
|
|
<i class="bi bi-github me-1"></i> GitHub Repository
|
|
</a>
|
|
</p>
|
|
<p class="mb-0 d-inline-flex align-items-center">
|
|
Built with
|
|
<img src="static/images/favicon.ico" alt="Icon" width="18" height="18" class="mx-1">
|
|
<span class="fw-semibold text-dark me-1"> Skoci Admin</span> • v2.2
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- modal -->
|
|
<div class="modal fade" id="confirmModal" tabindex="-1" aria-labelledby="confirmModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="confirmModalLabel">
|
|
Information
|
|
</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
|
|
<div class="modal-body">
|
|
<div class="mt-3">
|
|
<p class="px-3">This is where you can provide detailed information, announcements, or a user guide for your application.</p>
|
|
<hr class="my-4">
|
|
<div class="d-flex justify-content-end mb-4">
|
|
<button type="button" class="btn bz-btn-outline-primary btn-bz-size me-2" data-bs-dismiss="modal">Cancel</button>
|
|
<button type="button" class="btn bz-btn-primary btn-bz-size" name="action">Submit</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<script>
|
|
// Preview Image Browse
|
|
$(document).ready(function() {
|
|
$('#id_image').change(async function(e) {
|
|
const file = this.files[0];
|
|
|
|
// 1. Tampilkan nama file
|
|
// $('#fileName').text(`${file.name} (${formatFileSize(file.size)})`);
|
|
$('#fileName').text(file.name);
|
|
|
|
try {
|
|
// 2. Kompres gambar hingga di bawah 1MB
|
|
const compressedImage = await compressToMax1MB(file);
|
|
|
|
// 3. Lakukan crop 4:3 setelah kompresi
|
|
const img = new Image();
|
|
img.onload = function() {
|
|
const croppedUrl = cropTo4_3Ratio(img);
|
|
$('#imagePreview').attr('src', croppedUrl).show();
|
|
$('#fileInfo').text(`Ukuran akhir: ${formatFileSize(getDataSize(croppedUrl))}`);
|
|
};
|
|
img.src = compressedImage;
|
|
} catch (error) {
|
|
alert('Gagal memproses gambar: ' + error.message);
|
|
}
|
|
});
|
|
|
|
// Fungsi kompresi dengan target maksimal 1MB
|
|
async function compressToMax1MB(file) {
|
|
let quality = 0.9; // Mulai dengan kualitas 90%
|
|
let result;
|
|
|
|
// Kompresi bertahap hingga ukuran di bawah 1MB
|
|
do {
|
|
result = await compressImage(file, quality);
|
|
quality -= 0.1; // Turunkan kualitas 10% setiap iterasi
|
|
|
|
if (quality < 0.1) {
|
|
throw new Error('Gambar terlalu besar untuk dikompresi ke bawah 1MB');
|
|
}
|
|
} while (result.dataSize > 1024 * 1024); // 1MB
|
|
return result.url;
|
|
}
|
|
|
|
// Fungsi kompresi gambar
|
|
function compressImage(file, quality) {
|
|
return new Promise((resolve) => {
|
|
const reader = new FileReader();
|
|
reader.onload = function(e) {
|
|
const img = new Image();
|
|
img.onload = function() {
|
|
const canvas = document.createElement('canvas');
|
|
const ctx = canvas.getContext('2d');
|
|
|
|
// Hitung ukuran baru dengan menjaga aspect ratio
|
|
const maxDimension = 2000; // Batas maksimum dimensi
|
|
let width = img.width;
|
|
let height = img.height;
|
|
|
|
if (width > height && width > maxDimension) {
|
|
height = (maxDimension / width) * height;
|
|
width = maxDimension;
|
|
} else if (height > maxDimension) {
|
|
width = (maxDimension / height) * width;
|
|
height = maxDimension;
|
|
}
|
|
|
|
canvas.width = width;
|
|
canvas.height = height;
|
|
|
|
// Gambar ulang dengan ukuran baru
|
|
ctx.drawImage(img, 0, 0, width, height);
|
|
|
|
// Konversi ke JPEG
|
|
const imageUrl = canvas.toDataURL('image/jpeg', quality);
|
|
resolve({
|
|
url: imageUrl,
|
|
dataSize: getDataSize(imageUrl)
|
|
});
|
|
};
|
|
img.src = e.target.result;
|
|
};
|
|
reader.readAsDataURL(file);
|
|
});
|
|
}
|
|
|
|
// Fungsi crop dengan rasio 4:3
|
|
function cropTo4_3Ratio(img) {
|
|
const targetRatio = 4/3;
|
|
let cropWidth, cropHeight;
|
|
|
|
// Hitung area crop
|
|
if (img.width/img.height > targetRatio) {
|
|
cropHeight = img.height;
|
|
cropWidth = cropHeight * targetRatio;
|
|
} else {
|
|
cropWidth = img.width;
|
|
cropHeight = cropWidth / targetRatio;
|
|
}
|
|
|
|
// Hitung posisi crop (center)
|
|
const x = (img.width - cropWidth)/2;
|
|
const y = (img.height - cropHeight)/2;
|
|
|
|
// Buat canvas untuk hasil crop
|
|
const canvas = document.createElement('canvas');
|
|
canvas.width = cropWidth;
|
|
canvas.height = cropHeight;
|
|
|
|
const ctx = canvas.getContext('2d');
|
|
ctx.drawImage(img, x, y, cropWidth, cropHeight, 0, 0, cropWidth, cropHeight);
|
|
|
|
return canvas.toDataURL('image/jpeg', 0.8);
|
|
}
|
|
|
|
// Helper functions
|
|
function getDataSize(dataUrl) {
|
|
return Math.round((dataUrl.length - 'data:image/jpeg;base64,'.length) * 3/4);
|
|
}
|
|
|
|
function formatFileSize(bytes) {
|
|
if (bytes < 1024) return bytes + ' bytes';
|
|
else if (bytes < 1048576) return (bytes/1024).toFixed(1) + ' KB';
|
|
else return (bytes/1048576).toFixed(1) + ' MB';
|
|
}
|
|
});
|
|
</script>
|
|
<script src="static/js/main.js"></script>
|
|
<script src="static/vendor/bootstrap/bootstrap.bundle.min.js"></script>
|
|
</body>
|
|
</html> |