DN WH1.0.1
This commit is contained in:
parent
04c4db511d
commit
4075547917
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -17,7 +17,8 @@ def project_context(request):
|
||||
"project_address": settings.app_address,
|
||||
"project_phone": settings.app_phone,
|
||||
"project_email": settings.app_email,
|
||||
"app_settings": settings, # Passing the whole object for easier access to new fields
|
||||
"project_image_url": os.getenv("PROJECT_IMAGE_URL", ""),
|
||||
# Used for cache-busting static assets
|
||||
"deployment_timestamp": int(time.time()),
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,13 +4,20 @@ from .models import Supplier, Faktur, Medicine, Batch, StockTransaction, Categor
|
||||
class AppSettingForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = AppSetting
|
||||
fields = ['app_name', 'app_description', 'app_address', 'app_phone', 'app_email']
|
||||
fields = [
|
||||
'app_name', 'app_description', 'app_address', 'app_phone', 'app_email',
|
||||
'theme_color', 'font_family', 'font_color', 'sidebar_theme'
|
||||
]
|
||||
widgets = {
|
||||
'app_name': forms.TextInput(attrs={'class': 'form-control'}),
|
||||
'app_description': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}),
|
||||
'app_address': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}),
|
||||
'app_phone': forms.TextInput(attrs={'class': 'form-control'}),
|
||||
'app_email': forms.EmailInput(attrs={'class': 'form-control'}),
|
||||
'theme_color': forms.Select(attrs={'class': 'form-select'}),
|
||||
'font_family': forms.Select(attrs={'class': 'form-select'}),
|
||||
'font_color': forms.TextInput(attrs={'class': 'form-control', 'type': 'color'}),
|
||||
'sidebar_theme': forms.Select(attrs={'class': 'form-select'}),
|
||||
}
|
||||
|
||||
class CategoryForm(forms.ModelForm):
|
||||
@ -116,4 +123,4 @@ class StockOutForm(forms.Form):
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
elif self.initial.get('medicine'):
|
||||
self.fields['batch'].queryset = Batch.objects.filter(medicine_id=self.initial.get('medicine'), quantity__gt=0)
|
||||
self.fields['batch'].queryset = Batch.objects.filter(medicine_id=self.initial.get('medicine'), quantity__gt=0)
|
||||
@ -0,0 +1,33 @@
|
||||
# Generated by Django 5.2.7 on 2026-02-06 12:04
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('core', '0004_appsetting'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='appsetting',
|
||||
name='font_color',
|
||||
field=models.CharField(default='#2d3748', max_length=7, verbose_name='Warna Font Utama'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='appsetting',
|
||||
name='font_family',
|
||||
field=models.CharField(choices=[('Inter', 'Inter (Modern)'), ('Poppins', 'Poppins (Friendly)'), ('Roboto', 'Roboto (Clean)'), ('Montserrat', 'Montserrat (Elegant)'), ('Playfair Display', 'Playfair (Classic)')], default='Inter', max_length=50, verbose_name='Jenis Font'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='appsetting',
|
||||
name='sidebar_theme',
|
||||
field=models.CharField(choices=[('light', 'Light'), ('dark', 'Dark'), ('glass', 'Glassmorphism')], default='glass', max_length=20, verbose_name='Gaya Sidebar'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='appsetting',
|
||||
name='theme_color',
|
||||
field=models.CharField(choices=[('primary', 'Ocean Blue'), ('success', 'Emerald Green'), ('indigo', 'Royal Purple'), ('orange', 'Sunset Orange'), ('dark', 'Midnight Dark'), ('secondary', 'Minimalist Gray')], default='primary', max_length=20, verbose_name='Warna Tema'),
|
||||
),
|
||||
]
|
||||
18
core/migrations/0006_alter_appsetting_theme_color.py
Normal file
18
core/migrations/0006_alter_appsetting_theme_color.py
Normal file
@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.2.7 on 2026-02-06 12:17
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('core', '0005_appsetting_font_color_appsetting_font_family_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='appsetting',
|
||||
name='theme_color',
|
||||
field=models.CharField(choices=[('primary', 'Ocean Blue'), ('success', 'Emerald Green'), ('indigo', 'Royal Purple'), ('orange', 'Sunset Orange'), ('dark', 'Midnight Dark'), ('secondary', 'Minimalist Gray'), ('white', 'Clean White')], default='primary', max_length=20, verbose_name='Warna Tema'),
|
||||
),
|
||||
]
|
||||
Binary file not shown.
Binary file not shown.
@ -2,12 +2,62 @@ from django.db import models
|
||||
from django.utils import timezone
|
||||
|
||||
class AppSetting(models.Model):
|
||||
THEME_CHOICES = [
|
||||
('primary', 'Ocean Blue'),
|
||||
('success', 'Emerald Green'),
|
||||
('indigo', 'Royal Purple'),
|
||||
('orange', 'Sunset Orange'),
|
||||
('dark', 'Midnight Dark'),
|
||||
('secondary', 'Minimalist Gray'),
|
||||
('white', 'Clean White'),
|
||||
]
|
||||
|
||||
FONT_CHOICES = [
|
||||
('Inter', 'Inter (Modern)'),
|
||||
('Poppins', 'Poppins (Friendly)'),
|
||||
('Roboto', 'Roboto (Clean)'),
|
||||
('Montserrat', 'Montserrat (Elegant)'),
|
||||
('Playfair Display', 'Playfair (Classic)'),
|
||||
]
|
||||
|
||||
app_name = models.CharField(max_length=100, default="DN-WRS", verbose_name="Nama Aplikasi")
|
||||
app_description = models.TextField(blank=True, verbose_name="Deskripsi Aplikasi")
|
||||
app_address = models.TextField(blank=True, verbose_name="Alamat")
|
||||
app_phone = models.CharField(max_length=20, blank=True, verbose_name="Nomor Telepon")
|
||||
app_email = models.EmailField(blank=True, verbose_name="Email")
|
||||
|
||||
# Theme Management
|
||||
theme_color = models.CharField(max_length=20, choices=THEME_CHOICES, default='primary', verbose_name="Warna Tema")
|
||||
font_family = models.CharField(max_length=50, choices=FONT_CHOICES, default='Inter', verbose_name="Jenis Font")
|
||||
font_color = models.CharField(max_length=7, default="#2d3748", verbose_name="Warna Font Utama")
|
||||
sidebar_theme = models.CharField(max_length=20, choices=[('light', 'Light'), ('dark', 'Dark'), ('glass', 'Glassmorphism')], default='glass', verbose_name="Gaya Sidebar")
|
||||
|
||||
@property
|
||||
def theme_hex(self):
|
||||
colors = {
|
||||
'primary': '#0d6efd',
|
||||
'success': '#10b981',
|
||||
'indigo': '#6366f1',
|
||||
'orange': '#f59e0b',
|
||||
'dark': '#1e293b',
|
||||
'secondary': '#64748b',
|
||||
'white': '#ffffff',
|
||||
}
|
||||
return colors.get(self.theme_color, '#0d6efd')
|
||||
|
||||
@property
|
||||
def theme_gradient_end(self):
|
||||
colors = {
|
||||
'primary': '#00d2ff',
|
||||
'success': '#34d399',
|
||||
'indigo': '#a855f7',
|
||||
'orange': '#fbbf24',
|
||||
'dark': '#475569',
|
||||
'secondary': '#94a3b8',
|
||||
'white': '#f8fafc',
|
||||
}
|
||||
return colors.get(self.theme_color, '#00d2ff')
|
||||
|
||||
def __str__(self):
|
||||
return self.app_name
|
||||
|
||||
@ -15,6 +65,7 @@ class AppSetting(models.Model):
|
||||
verbose_name = "Pengaturan Aplikasi"
|
||||
verbose_name_plural = "Pengaturan Aplikasi"
|
||||
|
||||
# ... rest of the file stays same
|
||||
class Category(models.Model):
|
||||
name = models.CharField(max_length=100, verbose_name="Nama Kategori")
|
||||
description = models.TextField(blank=True, verbose_name="Deskripsi")
|
||||
@ -145,4 +196,4 @@ class StockTransaction(models.Model):
|
||||
|
||||
class Meta:
|
||||
verbose_name_plural = "Transaksi Stok"
|
||||
verbose_name = "Transaksi Stok"
|
||||
verbose_name = "Transaksi Stok"
|
||||
|
||||
@ -7,10 +7,22 @@
|
||||
<title>{{ project_name|default:"DN-WRS" }}</title>
|
||||
<!-- Bootstrap 5 -->
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<!-- Google Fonts: Plus Jakarta Sans -->
|
||||
|
||||
<!-- Dynamic Google Fonts -->
|
||||
<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=Plus+Jakarta+Sans:wght@300;400;500;600;700;800&display=swap" rel="stylesheet">
|
||||
{% if app_settings.font_family == 'Poppins' %}
|
||||
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
||||
{% elif app_settings.font_family == 'Roboto' %}
|
||||
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap" rel="stylesheet">
|
||||
{% elif app_settings.font_family == 'Montserrat' %}
|
||||
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
||||
{% elif app_settings.font_family == 'Playfair Display' %}
|
||||
<link href="https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
{% else %}
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
||||
{% endif %}
|
||||
|
||||
<!-- Lucide Icons -->
|
||||
<script src="https://unpkg.com/lucide@latest"></script>
|
||||
<!-- Chart.js -->
|
||||
@ -20,19 +32,38 @@
|
||||
|
||||
<style>
|
||||
:root {
|
||||
--primary-gradient: linear-gradient(135deg, #0d6efd 0%, #00d2ff 100%);
|
||||
--primary-color: {{ app_settings.theme_hex|default:'#0d6efd' }};
|
||||
--primary-gradient: linear-gradient(135deg, {{ app_settings.theme_hex|default:'#0d6efd' }} 0%, {{ app_settings.theme_gradient_end|default:'#00d2ff' }} 100%);
|
||||
--sidebar-width: 280px;
|
||||
--glass-bg: rgba(255, 255, 255, 0.8);
|
||||
--glass-border: rgba(255, 255, 255, 0.3);
|
||||
--glass-bg: rgba(255, 255, 255, 0.85);
|
||||
--glass-border: rgba(255, 255, 255, 0.4);
|
||||
--text-main: {{ app_settings.font_color|default:'#2d3748' }};
|
||||
--font-family: '{{ app_settings.font_family|default:"Inter" }}', sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Plus Jakarta Sans', sans-serif;
|
||||
background-color: #f8f9fa;
|
||||
color: #212529;
|
||||
font-family: var(--font-family);
|
||||
background-color: #f8fafc;
|
||||
color: var(--text-main);
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: var(--primary-color);
|
||||
border-color: var(--primary-color);
|
||||
}
|
||||
.btn-primary:hover {
|
||||
background-color: var(--primary-color);
|
||||
filter: brightness(0.9);
|
||||
border-color: var(--primary-color);
|
||||
}
|
||||
.text-primary {
|
||||
color: var(--primary-color) !important;
|
||||
}
|
||||
.bg-primary {
|
||||
background-color: var(--primary-color) !important;
|
||||
}
|
||||
|
||||
/* Sidebar Styles */
|
||||
.sidebar {
|
||||
width: var(--sidebar-width);
|
||||
@ -40,12 +71,24 @@
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
background: #fff;
|
||||
border-right: 1px solid #e9ecef;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
z-index: 1040;
|
||||
transition: transform 0.3s ease;
|
||||
|
||||
{% if app_settings.sidebar_theme == 'dark' %}
|
||||
background: #1e293b;
|
||||
border-right: 1px solid #334155;
|
||||
color: #f1f5f9;
|
||||
{% elif app_settings.sidebar_theme == 'light' %}
|
||||
background: #ffffff;
|
||||
border-right: 1px solid #e2e8f0;
|
||||
color: #1e293b;
|
||||
{% else %}
|
||||
background: var(--glass-bg);
|
||||
backdrop-filter: blur(15px);
|
||||
border-right: 1px solid var(--glass-border);
|
||||
{% endif %}
|
||||
}
|
||||
|
||||
.main-wrapper {
|
||||
@ -82,30 +125,58 @@
|
||||
font-size: 0.7rem;
|
||||
text-transform: uppercase;
|
||||
font-weight: 700;
|
||||
color: #adb5bd;
|
||||
letter-spacing: 0.05rem;
|
||||
{% if app_settings.sidebar_theme == 'dark' %}
|
||||
color: #94a3b8;
|
||||
{% else %}
|
||||
color: #64748b;
|
||||
{% endif %}
|
||||
}
|
||||
|
||||
.nav-item-link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0.75rem 1rem;
|
||||
color: #495057;
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
border-radius: 12px;
|
||||
margin-bottom: 0.25rem;
|
||||
transition: all 0.2s ease;
|
||||
{% if app_settings.sidebar_theme == 'dark' %}
|
||||
color: #cbd5e1;
|
||||
{% else %}
|
||||
color: #475569;
|
||||
{% endif %}
|
||||
}
|
||||
|
||||
.nav-item-link:hover {
|
||||
background: #f8f9fa;
|
||||
color: #0d6efd;
|
||||
{% if app_settings.sidebar_theme == 'dark' %}
|
||||
background: #334155;
|
||||
color: #fff;
|
||||
{% else %}
|
||||
background: #f1f5f9;
|
||||
color: var(--primary-color);
|
||||
{% endif %}
|
||||
}
|
||||
|
||||
.nav-item-link.active {
|
||||
background: #e7f1ff;
|
||||
color: #0d6efd;
|
||||
{% if app_settings.sidebar_theme == 'dark' %}
|
||||
background: var(--primary-color);
|
||||
color: #fff;
|
||||
{% else %}
|
||||
background: rgba(var(--primary-color-rgb, 13, 110, 253), 0.1);
|
||||
color: var(--primary-color);
|
||||
{% endif %}
|
||||
}
|
||||
|
||||
/* Hack for active state color in light/glass theme */
|
||||
.nav-item-link.active {
|
||||
{% if app_settings.sidebar_theme != 'dark' %}
|
||||
background-color: var(--primary-color);
|
||||
background-image: var(--primary-gradient);
|
||||
color: white;
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
|
||||
{% endif %}
|
||||
}
|
||||
|
||||
.nav-item-link i {
|
||||
@ -114,10 +185,10 @@
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
/* Top Header in Main Wrapper */
|
||||
/* Top Header */
|
||||
.top-header {
|
||||
height: 70px;
|
||||
background: rgba(248, 249, 250, 0.8);
|
||||
background: rgba(248, 250, 252, 0.8);
|
||||
backdrop-filter: blur(10px);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@ -127,31 +198,22 @@
|
||||
z-index: 1030;
|
||||
}
|
||||
|
||||
.search-container {
|
||||
position: relative;
|
||||
max-width: 400px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.search-container input {
|
||||
padding-left: 40px;
|
||||
border-radius: 50px;
|
||||
border-radius: 12px;
|
||||
background: #fff;
|
||||
border: 1px solid #e9ecef;
|
||||
border: 1px solid #e2e8f0;
|
||||
height: 42px;
|
||||
}
|
||||
|
||||
.search-container i {
|
||||
position: absolute;
|
||||
left: 15px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
color: #adb5bd;
|
||||
|
||||
.search-container input:focus {
|
||||
border-color: var(--primary-color);
|
||||
box-shadow: 0 0 0 3px rgba(var(--primary-color-rgb, 13, 110, 253), 0.15);
|
||||
}
|
||||
|
||||
.user-profile-btn {
|
||||
background: #fff;
|
||||
border: 1px solid #e9ecef;
|
||||
border: 1px solid #e2e8f0;
|
||||
padding: 5px 15px 5px 5px;
|
||||
border-radius: 50px;
|
||||
display: flex;
|
||||
@ -160,52 +222,34 @@
|
||||
}
|
||||
|
||||
.user-profile-btn:hover {
|
||||
border-color: #0d6efd;
|
||||
background: #f8f9fa;
|
||||
border-color: var(--primary-color);
|
||||
background: #f8fafc;
|
||||
}
|
||||
|
||||
/* Mobile Adjustments */
|
||||
@media (max-width: 991.98px) {
|
||||
.sidebar {
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
.sidebar.show {
|
||||
transform: translateX(0);
|
||||
}
|
||||
.main-wrapper {
|
||||
margin-left: 0;
|
||||
}
|
||||
.sidebar { transform: translateX(-100%); }
|
||||
.sidebar.show { transform: translateX(0); }
|
||||
.main-wrapper { margin-left: 0; }
|
||||
.sidebar-overlay {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
top: 0; left: 0; right: 0; bottom: 0;
|
||||
background: rgba(0,0,0,0.5);
|
||||
z-index: 1035;
|
||||
backdrop-filter: blur(4px);
|
||||
}
|
||||
.sidebar-overlay.show {
|
||||
display: block;
|
||||
}
|
||||
.sidebar-overlay.show { display: block; }
|
||||
}
|
||||
|
||||
.fade-in {
|
||||
animation: fadeIn 0.5s ease-in;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
}
|
||||
.fade-in { animation: fadeIn 0.4s ease-out; }
|
||||
@keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
|
||||
</style>
|
||||
{% block extra_head %}{% endblock %}
|
||||
{% block extra_css %}{% endblock %}
|
||||
</head>
|
||||
<body>
|
||||
{% if user.is_authenticated %}
|
||||
<div class="sidebar-overlay" id="sidebarOverlay"></div>
|
||||
|
||||
<!-- Sidebar -->
|
||||
<aside class="sidebar" id="sidebar">
|
||||
<a class="sidebar-brand" href="{% url 'home' %}">
|
||||
<i data-lucide="package" class="me-2 text-primary" style="width: 32px; height: 32px;"></i>
|
||||
@ -249,7 +293,7 @@
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="p-3 border-top">
|
||||
<div class="p-3 border-top {% if app_settings.sidebar_theme == 'dark' %}border-secondary{% endif %}">
|
||||
<form method="post" action="{% url 'logout' %}">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="nav-item-link text-danger border-0 bg-transparent w-100 text-start">
|
||||
@ -258,22 +302,23 @@
|
||||
</form>
|
||||
</div>
|
||||
</aside>
|
||||
{% endif %}
|
||||
|
||||
<div class="main-wrapper">
|
||||
<!-- Top Header -->
|
||||
<div class="{% if user.is_authenticated %}main-wrapper{% endif %}">
|
||||
{% if user.is_authenticated %}
|
||||
<header class="top-header">
|
||||
<button class="btn btn-link p-0 me-3 d-lg-none text-dark shadow-none" id="sidebarToggle">
|
||||
<i data-lucide="menu"></i>
|
||||
</button>
|
||||
|
||||
<form action="{% url 'medicine_list' %}" method="get" class="search-container d-none d-md-block">
|
||||
<i data-lucide="search"></i>
|
||||
<form action="{% url 'medicine_list' %}" method="get" class="search-container d-none d-md-block" style="position: relative; max-width: 400px; width: 100%;">
|
||||
<i data-lucide="search" style="position: absolute; left: 15px; top: 50%; transform: translateY(-50%); color: #adb5bd;"></i>
|
||||
<input type="text" name="q" class="form-control border-0 shadow-sm" placeholder="Cari barang atau faktur..." value="{{ query|default:'' }}">
|
||||
</form>
|
||||
|
||||
<div class="ms-auto d-flex align-items-center">
|
||||
<div class="dropdown">
|
||||
<button class="user-profile-btn shadow-none border-0 d-flex align-items-center" type="button" data-bs-toggle="dropdown">
|
||||
<button class="user-profile-btn shadow-none border-0" type="button" data-bs-toggle="dropdown">
|
||||
<div class="bg-primary text-white rounded-circle d-flex align-items-center justify-content-center me-2" style="width: 32px; height: 32px; font-weight: 700; font-size: 0.8rem;">
|
||||
{{ user.username|slice:":1"|upper }}
|
||||
</div>
|
||||
@ -293,9 +338,10 @@
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
{% endif %}
|
||||
|
||||
<div class="container-fluid px-4 py-4">
|
||||
{% if messages %}
|
||||
<div class="{% if user.is_authenticated %}container-fluid px-4 py-4{% else %}container py-5{% endif %}">
|
||||
{% if user.is_authenticated and messages %}
|
||||
{% for message in messages %}
|
||||
<div class="alert alert-{{ message.tags }} alert-dismissible fade show rounded-4 border-0 shadow-sm mb-4" role="alert">
|
||||
<div class="d-flex align-items-center">
|
||||
@ -313,11 +359,12 @@
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
<main class="fade-in">
|
||||
<main class="{% if user.is_authenticated %}fade-in{% endif %}">
|
||||
{% block content %}{% endblock %}
|
||||
</main>
|
||||
</div>
|
||||
|
||||
{% if user.is_authenticated %}
|
||||
<footer class="mt-auto py-4 bg-white border-top">
|
||||
<div class="container-fluid px-4">
|
||||
<div class="row align-items-center">
|
||||
@ -332,19 +379,13 @@
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% else %}
|
||||
<main>
|
||||
{% block login_content %}{% block content_no_auth %}{% endblock %}{% endblock %}
|
||||
</main>
|
||||
{% endif %}
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
||||
<script>
|
||||
// Initialize Lucide icons
|
||||
lucide.createIcons();
|
||||
|
||||
// Sidebar Toggle for Mobile
|
||||
const sidebar = document.getElementById('sidebar');
|
||||
const overlay = document.getElementById('sidebarOverlay');
|
||||
const toggle = document.getElementById('sidebarToggle');
|
||||
|
||||
@ -3,28 +3,32 @@
|
||||
|
||||
{% block content %}
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-8">
|
||||
<div class="card border-0 shadow-lg rounded-4 overflow-hidden mb-4">
|
||||
<div class="card-header bg-white border-0 py-4 px-4">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="bg-primary bg-opacity-10 p-3 rounded-4 me-3">
|
||||
<i data-lucide="settings" class="text-primary"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h4 class="fw-bold mb-0">Pengaturan Aplikasi</h4>
|
||||
<p class="text-muted small mb-0">Konfigurasi identitas sistem pergudangan</p>
|
||||
<div class="col-lg-10">
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
|
||||
<div class="card border-0 shadow-lg rounded-4 overflow-hidden mb-4">
|
||||
<div class="card-header bg-white border-0 py-4 px-4">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="bg-primary bg-opacity-10 p-3 rounded-4 me-3">
|
||||
<i data-lucide="settings" class="text-primary"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h4 class="fw-bold mb-0">Pengaturan Aplikasi</h4>
|
||||
<p class="text-muted small mb-0">Konfigurasi identitas dan tampilan sistem</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body p-4">
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
|
||||
<div class="card-body p-4">
|
||||
<div class="row">
|
||||
<!-- Identitas Aplikasi -->
|
||||
<div class="col-md-12 mb-4">
|
||||
<h5 class="fw-bold mb-3 border-bottom pb-2">Identitas Aplikasi</h5>
|
||||
</div>
|
||||
|
||||
<div class="col-md-12 mb-4">
|
||||
<label class="form-label fw-semibold">Nama Aplikasi</label>
|
||||
{{ form.app_name }}
|
||||
<div class="form-text">Nama ini akan muncul di navigasi dan judul halaman.</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-12 mb-4">
|
||||
@ -32,6 +36,40 @@
|
||||
{{ form.app_description }}
|
||||
</div>
|
||||
|
||||
<!-- Tampilan & Gaya -->
|
||||
<div class="col-md-12 mb-4 mt-2">
|
||||
<h5 class="fw-bold mb-3 border-bottom pb-2">Tampilan & Gaya</h5>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 mb-4">
|
||||
<label class="form-label fw-semibold">Warna Tema (Aksen)</label>
|
||||
{{ form.theme_color }}
|
||||
<div class="form-text">Warna utama untuk tombol dan aksen UI.</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 mb-4">
|
||||
<label class="form-label fw-semibold">Gaya Sidebar</label>
|
||||
{{ form.sidebar_theme }}
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 mb-4">
|
||||
<label class="form-label fw-semibold">Jenis Font</label>
|
||||
{{ form.font_family }}
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 mb-4">
|
||||
<label class="form-label fw-semibold">Warna Font Utama</label>
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
{{ form.font_color }}
|
||||
<span class="text-muted small">Pilih warna teks global</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Kontak -->
|
||||
<div class="col-md-12 mb-4 mt-2">
|
||||
<h5 class="fw-bold mb-3 border-bottom pb-2">Kontak & Alamat</h5>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 mb-4">
|
||||
<label class="form-label fw-semibold">Nomor Telepon</label>
|
||||
{{ form.app_phone }}
|
||||
@ -54,9 +92,9 @@
|
||||
<i data-lucide="save" class="me-2 icon-sm"></i> Simpan Perubahan
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="card border-0 shadow-sm rounded-4 mb-4">
|
||||
<div class="card-body p-4">
|
||||
@ -82,4 +120,4 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
Loading…
x
Reference in New Issue
Block a user