nano_bot / templates /dashboard.html
Dooratre's picture
Upload 7 files
3090b5a verified
<!DOCTYPE html>
<html lang="ar" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>نانو بوت - لوحة التحكم</title>
<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=Tajawal:wght@300;400;500;700;800&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
<style>
:root {
--primary-color: #4361ee;
--primary-light: #4895ef;
--primary-dark: #3f37c9;
--secondary-color: #4cc9f0;
--success-color: #4caf50;
--danger-color: #f72585;
--warning-color: #ff9e00;
--info-color: #3a86ff;
--light-color: #f8f9fa;
--dark-color: #212529;
--body-bg: #f0f5ff;
--card-bg: #ffffff;
--border-color: #e9ecef;
--text-color: #333;
--text-muted: #6c757d;
--shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.05);
--shadow-md: 0 5px 15px rgba(0, 0, 0, 0.07);
--shadow-lg: 0 10px 25px rgba(0, 0, 0, 0.1);
--transition: all 0.3s ease;
--border-radius: 12px;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Tajawal', sans-serif;
}
body {
background-color: var(--body-bg);
color: var(--text-color);
min-height: 100vh;
display: flex;
flex-direction: column;
}
/* Scrollbar Styling */
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 10px;
}
::-webkit-scrollbar-thumb {
background: var(--primary-light);
border-radius: 10px;
}
::-webkit-scrollbar-thumb:hover {
background: var(--primary-color);
}
/* Navigation */
.navbar {
background-color: var(--card-bg);
color: var(--text-color);
padding: 15px 20px;
display: flex;
justify-content: space-between;
align-items: center;
box-shadow: var(--shadow-md);
position: sticky;
top: 0;
z-index: 100;
}
.navbar-brand {
display: flex;
align-items: center;
font-size: 22px;
font-weight: 700;
color: var(--primary-color);
}
.navbar-brand svg {
width: 28px;
height: 28px;
margin-left: 10px;
fill: var(--primary-color);
}
.navbar-nav {
display: flex;
align-items: center;
}
.nav-item {
margin-right: 20px;
}
.nav-link {
color: var(--text-color);
text-decoration: none;
font-weight: 500;
transition: var(--transition);
display: flex;
align-items: center;
}
.nav-link:hover {
color: var(--primary-color);
}
.nav-link svg {
margin-left: 5px;
width: 18px;
height: 18px;
}
.container {
max-width: 1200px;
width: 100%;
margin: 0 auto;
padding: 20px;
flex: 1;
}
/* Dashboard Grid */
.dashboard-grid {
display: grid;
grid-template-columns: 1fr;
gap: 20px;
}
@media (min-width: 768px) {
.dashboard-grid {
grid-template-columns: 1fr 1fr;
}
}
@media (min-width: 1200px) {
.dashboard-grid {
grid-template-columns: 1fr 1fr 1fr;
}
}
/* Cards */
.card {
background-color: var(--card-bg);
border-radius: var(--border-radius);
box-shadow: var(--shadow-sm);
transition: var(--transition);
overflow: hidden;
height: 100%;
}
.card:hover {
box-shadow: var(--shadow-md);
transform: translateY(-3px);
}
.card-header {
padding: 15px 20px;
border-bottom: 1px solid var(--border-color);
display: flex;
justify-content: space-between;
align-items: center;
background-color: rgba(67, 97, 238, 0.05);
}
.card-title {
font-size: 18px;
font-weight: 700;
color: var(--primary-color);
display: flex;
align-items: center;
}
.card-title svg {
margin-left: 8px;
width: 20px;
height: 20px;
}
.card-body {
padding: 20px;
}
.card-footer {
padding: 15px 20px;
border-top: 1px solid var(--border-color);
background-color: rgba(67, 97, 238, 0.03);
}
/* Status Card */
.status-card {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
padding: 30px 20px;
}
.status-icon {
width: 80px;
height: 80px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 15px;
background-color: rgba(67, 97, 238, 0.1);
}
.status-icon svg {
width: 40px;
height: 40px;
fill: var(--primary-color);
}
.status-title {
font-size: 20px;
font-weight: 700;
margin-bottom: 10px;
}
.status-subtitle {
color: var(--text-muted);
margin-bottom: 20px;
}
/* Switch */
.switch-container {
display: flex;
align-items: center;
justify-content: center;
}
.switch {
position: relative;
display: inline-block;
width: 60px;
height: 34px;
margin: 0 10px;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
transition: .4s;
border-radius: 34px;
}
.slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
transition: .4s;
border-radius: 50%;
}
input:checked + .slider {
background-color: var(--success-color);
}
input:focus + .slider {
box-shadow: 0 0 1px var(--success-color);
}
input:checked + .slider:before {
transform: translateX(26px);
}
.switch-label {
font-weight: 500;
}
/* Info Cards */
.info-item {
display: flex;
align-items: center;
margin-bottom: 15px;
padding-bottom: 15px;
border-bottom: 1px solid var(--border-color);
}
.info-item:last-child {
margin-bottom: 0;
padding-bottom: 0;
border-bottom: none;
}
.info-icon {
width: 40px;
height: 40px;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
margin-left: 15px;
flex-shrink: 0;
}
.info-icon.primary {
background-color: rgba(67, 97, 238, 0.1);
color: var(--primary-color);
}
.info-icon.success {
background-color: rgba(76, 175, 80, 0.1);
color: var(--success-color);
}
.info-icon.warning {
background-color: rgba(255, 158, 0, 0.1);
color: var(--warning-color);
}
.info-icon svg {
width: 20px;
height: 20px;
}
.info-content {
flex: 1;
}
.info-label {
font-size: 14px;
color: var(--text-muted);
margin-bottom: 5px;
}
.info-value {
font-size: 16px;
font-weight: 700;
}
/* Forms */
.form-group {
margin-bottom: 20px;
}
.form-label {
display: block;
margin-bottom: 8px;
font-weight: 500;
}
.form-control {
width: 100%;
padding: 12px 15px;
border: 1px solid var(--border-color);
border-radius: 8px;
font-size: 16px;
transition: var(--transition);
background-color: var(--light-color);
}
.form-control:focus {
border-color: var(--primary-color);
outline: none;
box-shadow: 0 0 0 3px rgba(67, 97, 238, 0.1);
}
textarea.form-control {
min-height: 120px;
resize: vertical;
}
/* Buttons */
.btn {
display: inline-block;
padding: 10px 20px;
border: none;
border-radius: 8px;
font-size: 16px;
font-weight: 500;
cursor: pointer;
transition: var(--transition);
text-align: center;
text-decoration: none;
}
.btn-primary {
background-color: var(--primary-color);
color: white;
}
.btn-primary:hover {
background-color: var(--primary-dark);
}
.btn-success {
background-color: var(--success-color);
color: white;
}
.btn-success:hover {
background-color: #3d8b40;
}
.btn-danger {
background-color: var(--danger-color);
color: white;
}
.btn-danger:hover {
background-color: #d61a6c;
}
.btn-sm {
padding: 6px 12px;
font-size: 14px;
}
.btn-block {
display: block;
width: 100%;
}
/* Products List */
.product-list {
margin-top: 20px;
}
.product-item {
background-color: var(--light-color);
border-radius: 8px;
padding: 15px;
margin-bottom: 15px;
position: relative;
transition: var(--transition);
}
.product-item:hover {
box-shadow: var(--shadow-sm);
}
.product-title {
font-weight: 700;
margin-bottom: 5px;
padding-left: 30px;
}
.product-price {
color: var(--primary-color);
font-weight: 700;
margin-bottom: 10px;
}
.product-description {
color: var(--text-muted);
font-size: 14px;
margin-bottom: 10px;
}
.product-actions {
position: absolute;
top: 15px;
left: 15px;
display: flex;
gap: 5px;
}
.action-btn {
width: 30px;
height: 30px;
border-radius: 6px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: var(--transition);
}
.action-btn.edit {
background-color: rgba(58, 134, 255, 0.1);
color: var(--info-color);
}
.action-btn.delete {
background-color: rgba(247, 37, 133, 0.1);
color: var(--danger-color);
}
.action-btn:hover {
transform: translateY(-2px);
}
.action-btn svg {
width: 16px;
height: 16px;
}
/* Tabs */
.tabs {
display: flex;
border-bottom: 1px solid var(--border-color);
margin-bottom: 20px;
overflow-x: auto;
scrollbar-width: none; /* Firefox */
}
.tabs::-webkit-scrollbar {
display: none; /* Chrome, Safari, Opera */
}
.tab-item {
padding: 12px 20px;
font-weight: 500;
color: var(--text-muted);
cursor: pointer;
transition: var(--transition);
white-space: nowrap;
}
.tab-item.active {
color: var(--primary-color);
border-bottom: 2px solid var(--primary-color);
}
.tab-content {
display: none;
}
.tab-content.active {
display: block;
}
/* Modal */
.modal-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 1000;
opacity: 0;
visibility: hidden;
transition: var(--transition);
}
.modal-overlay.active {
opacity: 1;
visibility: visible;
}
.modal {
background-color: var(--card-bg);
border-radius: var(--border-radius);
width: 90%;
max-width: 500px;
max-height: 90vh;
overflow-y: auto;
box-shadow: var(--shadow-lg);
transform: translateY(20px);
transition: var(--transition);
}
.modal-overlay.active .modal {
transform: translateY(0);
}
.modal-header {
padding: 15px 20px;
border-bottom: 1px solid var(--border-color);
display: flex;
justify-content: space-between;
align-items: center;
}
.modal-title {
font-size: 18px;
font-weight: 700;
}
.modal-close {
background: none;
border: none;
cursor: pointer;
font-size: 20px;
color: var(--text-muted);
}
.modal-body {
padding: 20px;
}
.modal-footer {
padding: 15px 20px;
border-top: 1px solid var(--border-color);
display: flex;
justify-content: flex-end;
gap: 10px;
}
/* Notifications */
.notification-container {
position: fixed;
top: 20px;
left: 20px;
right: 20px;
z-index: 1001;
display: flex;
flex-direction: column;
align-items: center;
pointer-events: none;
}
.notification {
background-color: var(--card-bg);
border-radius: 8px;
box-shadow: var(--shadow-md);
padding: 15px 20px;
margin-bottom: 10px;
display: flex;
align-items: center;
width: 100%;
max-width: 400px;
transform: translateY(-20px);
opacity: 0;
transition: all 0.3s ease;
pointer-events: auto;
}
.notification.show {
transform: translateY(0);
opacity: 1;
}
.notification-icon {
width: 24px;
height: 24px;
margin-left: 15px;
flex-shrink: 0;
}
.notification-content {
flex: 1;
}
.notification-title {
font-weight: 700;
margin-bottom: 5px;
}
.notification-message {
font-size: 14px;
color: var(--text-muted);
}
.notification-close {
background: none;
border: none;
cursor: pointer;
color: var(--text-muted);
margin-right: -5px;
}
.notification.success .notification-icon {
color: var(--success-color);
}
.notification.error .notification-icon {
color: var(--danger-color);
}
.notification.info .notification-icon {
color: var(--info-color);
}
/* Loading */
.loading-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(255, 255, 255, 0.8);
display: flex;
justify-content: center;
align-items: center;
z-index: 2000;
opacity: 0;
visibility: hidden;
transition: var(--transition);
}
.loading-overlay.active {
opacity: 1;
visibility: visible;
}
.spinner {
width: 50px;
height: 50px;
border: 5px solid rgba(67, 97, 238, 0.2);
border-radius: 50%;
border-top-color: var(--primary-color);
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* Badges */
.badge {
display: inline-block;
padding: 4px 8px;
border-radius: 4px;
font-size: 12px;
font-weight: 700;
}
.badge-success {
background-color: rgba(76, 175, 80, 0.1);
color: var(--success-color);
}
.badge-danger {
background-color: rgba(247, 37, 133, 0.1);
color: var(--danger-color);
}
.badge-warning {
background-color: rgba(255, 158, 0, 0.1);
color: var(--warning-color);
}
/* Responsive Adjustments */
@media (max-width: 768px) {
.navbar {
padding: 10px 15px;
}
.navbar-brand {
font-size: 18px;
}
.container {
padding: 15px;
}
.card-header {
padding: 12px 15px;
}
.card-body {
padding: 15px;
}
.status-icon {
width: 60px;
height: 60px;
}
.status-icon svg {
width: 30px;
height: 30px;
}
.status-title {
font-size: 18px;
}
}
</style>
<style>
/* Message Badge */
.message-badge {
background-color: var(--danger-color);
color: white;
border-radius: 50%;
padding: 2px 6px;
font-size: 12px;
position: absolute;
top: -5px;
left: -5px;
font-weight: bold;
}
.nav-link {
position: relative;
}
/* Expiration Warning */
.expiration-warning {
color: var(--danger-color);
font-weight: 500;
margin-top: 5px;
font-size: 14px;
}
/* Confirmation Modal */
.confirm-modal {
background-color: var(--card-bg);
border-radius: var(--border-radius);
width: 90%;
max-width: 400px;
box-shadow: var(--shadow-lg);
padding: 20px;
text-align: center;
}
.confirm-title {
font-size: 18px;
font-weight: 700;
margin-bottom: 15px;
}
.confirm-message {
margin-bottom: 20px;
color: var(--text-muted);
}
.confirm-buttons {
display: flex;
justify-content: center;
gap: 10px;
}
/* Improved Product Display */
.product-item {
background-color: var(--light-color);
border-radius: 8px;
padding: 20px;
margin-bottom: 20px;
position: relative;
transition: var(--transition);
border: 1px solid var(--border-color);
}
.product-item:hover {
box-shadow: var(--shadow-md);
transform: translateY(-2px);
}
.product-title {
font-weight: 700;
font-size: 18px;
margin-bottom: 10px;
padding-left: 40px;
color: var(--primary-color);
}
.product-price {
color: var(--success-color);
font-weight: 700;
margin-bottom: 15px;
font-size: 16px;
}
.product-description {
color: var(--text-color);
font-size: 15px;
margin-bottom: 15px;
line-height: 1.5;
}
.product-info {
background-color: rgba(67, 97, 238, 0.05);
padding: 10px;
border-radius: 6px;
font-size: 14px;
color: var(--text-muted);
margin-top: 10px;
}
.product-actions {
position: absolute;
top: 20px;
left: 20px;
display: flex;
gap: 8px;
}
.action-btn {
width: 36px;
height: 36px;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: var(--transition);
}
.action-btn.edit {
background-color: rgba(58, 134, 255, 0.2);
color: var(--info-color);
}
.action-btn.delete {
background-color: rgba(247, 37, 133, 0.2);
color: var(--danger-color);
}
.action-btn:hover {
transform: translateY(-3px);
box-shadow: var(--shadow-sm);
}
.action-btn svg {
width: 18px;
height: 18px;
}
@media (max-width: 768px) {
.product-title {
font-size: 16px;
padding-left: 0;
margin-top: 40px; /* Space for the action buttons */
}
.product-actions {
top: 15px;
left: 15px;
right: 15px;
justify-content: flex-end;
}
}
/* Subscription and Expiration Warnings */
.subscription-warning {
color: var(--danger-color);
font-weight: 500;
margin-top: 5px;
font-size: 14px;
}
.expiration-warning {
color: var(--warning-color);
font-weight: 500;
margin-top: 5px;
font-size: 14px;
}
.expiration-error {
color: var(--danger-color);
font-weight: 700;
margin-top: 5px;
font-size: 14px;
}
.expired-date {
text-decoration: line-through;
color: var(--danger-color);
}
/* Improved Product Display */
.product-list {
margin-top: 20px;
}
.product-item {
background-color: #ffffff;
border-radius: 12px;
padding: 20px;
margin-bottom: 20px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
border: 1px solid #e9ecef;
transition: all 0.3s ease;
}
.product-item:hover {
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
transform: translateY(-3px);
}
.product-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 15px;
}
.product-title {
font-size: 18px;
font-weight: 700;
color: #4361ee;
flex: 1;
}
.product-actions {
display: flex;
gap: 8px;
}
.action-btn {
width: 36px;
height: 36px;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.3s ease;
}
.action-btn.edit {
background-color: rgba(58, 134, 255, 0.1);
color: #3a86ff;
}
.action-btn.delete {
background-color: rgba(247, 37, 133, 0.1);
color: #f72585;
}
.action-btn:hover {
transform: translateY(-2px);
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}
.action-btn svg {
width: 18px;
height: 18px;
}
.product-price {
color: #4caf50;
font-weight: 700;
font-size: 16px;
margin-bottom: 10px;
background-color: rgba(76, 175, 80, 0.1);
display: inline-block;
padding: 5px 10px;
border-radius: 6px;
}
.product-description {
margin-bottom: 15px;
line-height: 1.5;
color: #333;
}
.product-info {
background-color: rgba(67, 97, 238, 0.05);
padding: 12px;
border-radius: 8px;
font-size: 14px;
color: #6c757d;
}
.info-label {
font-weight: 700;
color: #4361ee;
}
/* Mobile Responsiveness for Products */
@media (max-width: 768px) {
.product-item {
padding: 15px;
}
.product-header {
flex-direction: column;
}
.product-title {
margin-bottom: 10px;
}
.product-actions {
align-self: flex-end;
}
}
.navbar .logo-icon {
width: 40px;
height: 40px;
background: linear-gradient(135deg, var(--primary-color), var(--primary-dark));
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 5px 15px rgba(67, 97, 238, 0.2);
position: relative;
overflow: hidden;
margin-left: 10px;
}
.navbar .logo-icon::before {
content: '';
position: absolute;
top: -10px;
left: -10px;
right: -10px;
bottom: -10px;
background: linear-gradient(135deg, rgba(255,255,255,0.2), rgba(255,255,255,0));
transform: rotate(35deg);
}
.navbar .logo-icon i {
color: white;
font-size: 20px;
position: relative;
z-index: 2;
}
.navbar .logo-text h1 {
font-size: 18px;
font-weight: 800;
margin: 0;
}
.navbar .logo-text p {
font-size: 12px;
margin: 0;
}
.navbar-brand {
display: flex;
align-items: center;
}
</style>
</head>
<body>
<!-- Loading Overlay -->
<div class="loading-overlay" id="loadingOverlay">
<div class="spinner"></div>
</div>
<!-- Notification Container -->
<div class="notification-container" id="notificationContainer"></div>
<!-- Navbar -->
<nav class="navbar">
<div class="navbar-brand">
<div class="logo-icon">
<i class="fas fa-robot"></i>
</div>
<div class="logo-text">
<h1>NANO BOT</h1>
</div>
</div>
<div class="navbar-nav">
<div class="nav-item">
<a href="{{ url_for('messages_page') }}" class="nav-link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
<path d="M20 4H4c-1.103 0-2 .897-2 2v12c0 1.103.897 2 2 2h16c1.103 0 2-.897 2-2V6c0-1.103-.897-2-2-2zm0 2v.511l-8 6.223-8-6.222V6h16zM4 18V9.044l7.386 5.745a.994.994 0 0 0 1.228 0L20 9.044 20.002 18H4z"/>
</svg>
الرسائل
{% if unread_count > 0 %}
<span class="message-badge">{{ unread_count }}</span>
{% endif %}
</a>
</div>
<div class="nav-item">
<a href="#" class="nav-link" id="logoutBtn">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
<path d="M16 13v-2H7V8l-5 4 5 4v-3z"/>
<path d="M20 3h-9c-1.103 0-2 .897-2 2v4h2V5h9v14h-9v-4H9v4c0 1.103.897 2 2 2h9c1.103 0 2-.897 2-2V5c0-1.103-.897-2-2-2z"/>
</svg>
تسجيل الخروج
</a>
</div>
</div>
</nav>
<!-- Main Container -->
<div class="container">
<div class="dashboard-grid">
<!-- Status Card -->
<div class="card">
<div class="card-header">
<h2 class="card-title">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
<path d="M12 2C6.486 2 2 6.486 2 12s4.486 10 10 10 10-4.486 10-10S17.514 2 12 2zm0 18c-4.411 0-8-3.589-8-8s3.589-8 8-8 8 3.589 8 8-3.589 8-8 8z"/>
<path d="M11 11h2v6h-2zm0-4h2v2h-2z"/>
</svg>
حالة البوت
</h2>
</div>
<div class="card-body status-card">
<div class="status-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
<path d="M12 2C6.486 2 2 6.486 2 12s4.486 10 10 10 10-4.486 10-10S17.514 2 12 2zm0 18c-4.411 0-8-3.589-8-8s3.589-8 8-8 8 3.589 8 8-3.589 8-8 8z"/>
<path d="M9.999 13.587 7.7 11.292l-1.412 1.416 3.713 3.705 6.706-6.706-1.414-1.414z"/>
</svg>
</div>
<h3 class="status-title">بوت الماسنجر</h3>
<p class="status-subtitle">تحكم في حالة البوت الخاص بك</p>
<div class="switch-container">
<span class="switch-label">تشغيل</span>
<label class="switch">
<input type="checkbox" id="botStatusToggle" {% if bot_status == 'ON' %}checked{% endif %}>
<span class="slider"></span>
</label>
<span class="switch-label">إيقاف</span>
</div>
</div>
</div>
<!-- Account Info Card -->
<div class="card">
<div class="card-header">
<h2 class="card-title">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
<path d="M12 2a5 5 0 1 0 5 5 5 5 0 0 0-5-5zm0 8a3 3 0 1 1 3-3 3 3 0 0 1-3 3zm9 11v-1a7 7 0 0 0-7-7h-4a7 7 0 0 0-7 7v1h2v-1a5 5 0 0 1 5-5h4a5 5 0 0 1 5 5v1z"/>
</svg>
معلومات الحساب
</h2>
</div>
<div class="card-body">
<div class="info-item">
<div class="info-icon primary">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
<path d="M12 2C6.486 2 2 6.486 2 12s4.486 10 10 10 10-4.486 10-10S17.514 2 12 2zm0 18c-4.411 0-8-3.589-8-8s3.589-8 8-8 8 3.589 8 8-3.589 8-8 8z"/>
<path d="M11 11h2v6h-2zm0-4h2v2h-2z"/>
</svg>
</div>
<div class="info-content">
<div class="info-label">اسم الصفحة</div>
<div class="info-value">{{ page.username }}</div>
</div>
</div>
<div class="info-item">
<div class="info-icon success">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
<path d="M21 11h-3V4a1 1 0 0 0-1-1H3a1 1 0 0 0-1 1v14c0 1.654 1.346 3 3 3h14c1.654 0 3-1.346 3-3v-6a1 1 0 0 0-1-1zM5 19a1 1 0 0 1-1-1V5h12v13c0 .351.061.688.171 1H5zm15-1a1 1 0 0 1-2 0v-5h2v5z"/>
<path d="M6 7h8v2H6zm0 4h8v2H6zm0 4h5v2H6z"/>
</svg>
</div>
<div class="info-content">
<div class="info-label">نوع الاشتراك</div>
<div class="info-value">{{ subscription_status }}</div>
{% if subscription_message %}
<div class="subscription-warning">{{ subscription_message }}</div>
{% endif %}
</div>
</div>
<div class="info-item">
<div class="info-icon warning">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
<path d="M12 2C6.486 2 2 6.486 2 12s4.486 10 10 10 10-4.486 10-10S17.514 2 12 2zm0 18c-4.411 0-8-3.589-8-8s3.589-8 8-8 8 3.589 8 8-3.589 8-8 8z"/>
<path d="M13 7h-2v5.414l3.293 3.293 1.414-1.414L13 11.586z"/>
</svg>
</div>
<div class="info-content">
<div class="info-label">تاريخ انتهاء الاشتراك</div>
<div class="info-value {% if is_expired %}expired-date{% endif %}">{{ expiration_date }}</div>
{% if expiration_message %}
<div class="{% if is_expired %}expiration-error{% else %}expiration-warning{% endif %}">{{ expiration_message }}</div>
{% endif %}
</div>
</div>
</div>
</div>
<!-- System Settings Card -->
<div class="card">
<div class="card-header">
<h2 class="card-title">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
<path d="M12 16c2.206 0 4-1.794 4-4s-1.794-4-4-4-4 1.794-4 4 1.794 4 4 4zm0-6c1.084 0 2 .916 2 2s-.916 2-2 2-2-.916-2-2 .916-2 2-2z"/>
<path d="m2.845 16.136 1 1.73c.531.917 1.809 1.261 2.73.73l.529-.306A8.1 8.1 0 0 0 9 19.402V20c0 1.103.897 2 2 2h2c1.103 0 2-.897 2-2v-.598a8.132 8.132 0 0 0 1.896-1.111l.529.306c.923.53 2.198.188 2.731-.731l.999-1.729a2.001 2.001 0 0 0-.731-2.732l-.505-.292a7.718 7.718 0 0 0 0-2.224l.505-.292a2.002 2.002 0 0 0 .731-2.732l-.999-1.729c-.531-.92-1.808-1.265-2.731-.732l-.529.306A8.1 8.1 0 0 0 15 4.598V4c0-1.103-.897-2-2-2h-2c-1.103 0-2 .897-2 2v.598a8.132 8.132 0 0 0-1.896 1.111l-.529-.306c-.924-.531-2.2-.187-2.731.732l-.999 1.729a2.001 2.001 0 0 0 .731 2.732l.505.292a7.683 7.683 0 0 0 0 2.223l-.505.292a2.003 2.003 0 0 0-.731 2.733zm3.326-2.758A5.703 5.703 0 0 1 6 12c0-.462.058-.926.17-1.378a.999.999 0 0 0-.47-1.108l-1.123-.65.998-1.729 1.145.662a.997.997 0 0 0 1.188-.142 6.071 6.071 0 0 1 2.384-1.399A1 1 0 0 0 11 5.3V4h2v1.3a1 1 0 0 0 .708.956 6.083 6.083 0 0 1 2.384 1.399.999.999 0 0 0 1.188.142l1.144-.661 1 1.729-1.124.649a1 1 0 0 0-.47 1.108c.112.452.17.916.17 1.378 0 .461-.058.925-.171 1.378a1 1 0 0 0 .471 1.108l1.123.649-.998 1.729-1.145-.661a.996.996 0 0 0-1.188.142 6.071 6.071 0 0 1-2.384 1.399A1 1 0 0 0 13 18.7l.002 1.3H11v-1.3a1 1 0 0 0-.708-.956 6.083 6.083 0 0 1-2.384-1.399.992.992 0 0 0-1.188-.141l-1.144.662-1-1.729 1.124-.651a1 1 0 0 0 .471-1.108z"/>
</svg>
إعدادات النظام
</h2>
</div>
<div class="card-body">
<div class="tabs">
<div class="tab-item active" data-tab="style">أسلوب الرد</div>
<div class="tab-item" data-tab="products">المنتجات</div>
</div>
<div class="tab-content active" id="style-tab">
<div class="form-group">
<label class="form-label">أسلوب الرد للبوت</label>
<textarea class="form-control" id="styleInput" rows="6" placeholder="أدخل أسلوب الرد الذي تريده للبوت...">{{ style }}</textarea>
</div>
<button class="btn btn-primary btn-block" id="saveStyleBtn">حفظ الأسلوب</button>
</div>
<div class="tab-content" id="products-tab">
<button class="btn btn-primary" id="addProductBtn">إضافة منتج جديد</button>
<div class="product-list" id="productsList">
{% for product in products %}
<div class="product-item" data-index="{{ loop.index0 }}">
<div class="product-header">
<div class="product-title">{{ product.name }}</div>
<div class="product-actions">
<div class="action-btn edit" onclick="editProduct({{ loop.index0 }})">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
<path d="M19.045 7.401c.378-.378.586-.88.586-1.414s-.208-1.036-.586-1.414l-1.586-1.586c-.378-.378-.88-.586-1.414-.586s-1.036.208-1.413.585L4 13.585V18h4.413L19.045 7.401zm-3-3 1.587 1.585-1.59 1.584-1.586-1.585 1.589-1.584zM6 16v-1.585l7.04-7.018 1.586 1.586L7.587 16H6zm-2 4h16v2H4z"/>
</svg>
</div>
<div class="action-btn delete" onclick="deleteProduct({{ loop.index0 }})">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
<path d="M5 20a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8h2V6h-4V4a2 2 0 0 0-2-2H9a2 2 0 0 0-2 2v2H3v2h2zM9 4h6v2H9zM8 8h9v12H7V8z"/>
<path d="M9 10h2v8H9zm4 0h2v8h-2z"/>
</svg>
</div>
</div>
</div>
<div class="product-price">{{ product.price }} دينار ليبي</div>
<div class="product-description">{{ product.description }}</div>
{% if product.info %}
<div class="product-info">
<span class="info-label">معلومات إضافية:</span> {{ product.info }}
</div>
{% endif %}
</div>
{% endfor %}
</div>
</div>
</div>
</div>
<!-- Add/Edit Product Modal -->
<div class="modal-overlay" id="productModal">
<div class="modal">
<div class="modal-header">
<h3 class="modal-title" id="productModalTitle">إضافة منتج جديد</h3>
<button class="modal-close" id="closeProductModal">&times;</button>
</div>
<div class="modal-body">
<div class="form-group">
<label class="form-label">اسم المنتج</label>
<input type="text" class="form-control" id="productName" placeholder="أدخل اسم المنتج">
</div>
<div class="form-group">
<label class="form-label">وصف المنتج</label>
<textarea class="form-control" id="productDescription" rows="3" placeholder="أدخل وصف المنتج"></textarea>
</div>
<div class="form-group">
<label class="form-label">السعر (دينار ليبي)</label>
<input type="text" class="form-control" id="productPrice" placeholder="أدخل سعر المنتج">
</div>
<div class="form-group">
<label class="form-label">معلومات إضافية</label>
<textarea class="form-control" id="productInfo" rows="2" placeholder="أدخل أي معلومات إضافية عن المنتج"></textarea>
</div>
<input type="hidden" id="productIndex" value="-1">
</div>
<div class="modal-footer">
<button class="btn btn-danger" id="cancelProductBtn">إلغاء</button>
<button class="btn btn-primary" id="saveProductBtn">حفظ المنتج</button>
</div>
</div>
</div>
<script>
// DOM Elements
const loadingOverlay = document.getElementById('loadingOverlay');
const notificationContainer = document.getElementById('notificationContainer');
const botStatusToggle = document.getElementById('botStatusToggle');
const styleInput = document.getElementById('styleInput');
const saveStyleBtn = document.getElementById('saveStyleBtn');
const addProductBtn = document.getElementById('addProductBtn');
const productsList = document.getElementById('productsList');
const productModal = document.getElementById('productModal');
const closeProductModal = document.getElementById('closeProductModal');
const cancelProductBtn = document.getElementById('cancelProductBtn');
const saveProductBtn = document.getElementById('saveProductBtn');
const productModalTitle = document.getElementById('productModalTitle');
const productName = document.getElementById('productName');
const productDescription = document.getElementById('productDescription');
const productPrice = document.getElementById('productPrice');
const productInfo = document.getElementById('productInfo');
const productIndex = document.getElementById('productIndex');
const tabItems = document.querySelectorAll('.tab-item');
const tabContents = document.querySelectorAll('.tab-content');
// WebSocket Connection
let socket;
function connectWebSocket() {
socket = io.connect(window.location.origin);
socket.on('connect', function() {
console.log('WebSocket connected');
});
socket.on('status_updated', function(data) {
showNotification('تم تحديث الحالة', 'تم تحديث حالة البوت بنجاح', 'success');
});
socket.on('style_updated', function(data) {
showNotification('تم تحديث الأسلوب', 'تم تحديث أسلوب الرد بنجاح', 'success');
});
socket.on('product_added', function(data) {
showNotification('تمت الإضافة', 'تمت إضافة المنتج بنجاح', 'success');
// Refresh the page to show the new product
setTimeout(() => {
window.location.reload();
}, 1500);
});
socket.on('product_deleted', function(data) {
showNotification('تم الحذف', 'تم حذف المنتج بنجاح', 'success');
// Refresh the page to update the products list
setTimeout(() => {
window.location.reload();
}, 1500);
});
socket.on('data_refreshed', function(data) {
showNotification('تم التحديث', 'تم تحديث البيانات بنجاح', 'info');
});
}
// Initialize
document.addEventListener('DOMContentLoaded', function() {
// Connect WebSocket
connectWebSocket();
// Initialize tabs
tabItems.forEach(item => {
item.addEventListener('click', () => {
const tabId = item.getAttribute('data-tab');
// Remove active class from all tabs
tabItems.forEach(tab => tab.classList.remove('active'));
tabContents.forEach(content => content.classList.remove('active'));
// Add active class to current tab
item.classList.add('active');
document.getElementById(`${tabId}-tab`).classList.add('active');
});
});
// Bot Status Toggle
botStatusToggle.addEventListener('change', function() {
updateBotStatus(this.checked ? 'ON' : 'OFF');
});
// Save Style Button
saveStyleBtn.addEventListener('click', function() {
updateStyle(styleInput.value);
});
// Add Product Button
addProductBtn.addEventListener('click', function() {
openProductModal();
});
// Close Product Modal
closeProductModal.addEventListener('click', function() {
closeModal(productModal);
});
// Cancel Product Button
cancelProductBtn.addEventListener('click', function() {
closeModal(productModal);
});
// Save Product Button
saveProductBtn.addEventListener('click', function() {
saveProduct();
});
});
// Functions
function showLoading() {
loadingOverlay.classList.add('active');
}
function hideLoading() {
loadingOverlay.classList.remove('active');
}
function showNotification(title, message, type = 'info') {
const notification = document.createElement('div');
notification.className = `notification ${type}`;
let iconSvg;
if (type === 'success') {
iconSvg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="notification-icon">
<path d="M12 2C6.486 2 2 6.486 2 12s4.486 10 10 10 10-4.486 10-10S17.514 2 12 2zm0 18c-4.411 0-8-3.589-8-8s3.589-8 8-8 8 3.589 8 8-3.589 8-8 8z"/>
<path d="M9.999 13.587 7.7 11.292l-1.412 1.416 3.713 3.705 6.706-6.706-1.414-1.414z"/>
</svg>`;
} else if (type === 'error') {
iconSvg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="notification-icon">
<path d="M12 2C6.486 2 2 6.486 2 12s4.486 10 10 10 10-4.486 10-10S17.514 2 12 2zm0 18c-4.411 0-8-3.589-8-8s3.589-8 8-8 8 3.589 8 8-3.589 8-8 8z"/>
<path d="M13 7h-2v7h2zm0 8h-2v2h2z"/>
</svg>`;
} else {
iconSvg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="notification-icon">
<path d="M12 2C6.486 2 2 6.486 2 12s4.486 10 10 10 10-4.486 10-10S17.514 2 12 2zm0 18c-4.411 0-8-3.589-8-8s3.589-8 8-8 8 3.589 8 8-3.589 8-8 8z"/>
<path d="M11 11h2v6h-2zm0-4h2v2h-2z"/>
</svg>`;
}
notification.innerHTML = `
${iconSvg}
<div class="notification-content">
<div class="notification-title">${title}</div>
<div class="notification-message">${message}</div>
</div>
<button class="notification-close">&times;</button>
`;
notificationContainer.appendChild(notification);
// Show notification with animation
setTimeout(() => {
notification.classList.add('show');
}, 10);
// Auto close after 5 seconds
setTimeout(() => {
closeNotification(notification);
}, 5000);
// Close button
notification.querySelector('.notification-close').addEventListener('click', function() {
closeNotification(notification);
});
}
function closeNotification(notification) {
notification.classList.remove('show');
setTimeout(() => {
notification.remove();
}, 300);
}
function updateBotStatus(status) {
showLoading();
fetch('/api/update_status', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ status: status }),
})
.then(response => response.json())
.then(data => {
hideLoading();
if (data.success) {
showNotification('تم تحديث الحالة', 'تم تحديث حالة البوت بنجاح', 'success');
} else {
showNotification('خطأ', data.message, 'error');
// Reset toggle to previous state
botStatusToggle.checked = status === 'OFF' ? false : true;
}
})
.catch(error => {
hideLoading();
showNotification('خطأ', 'حدث خطأ أثناء تحديث الحالة', 'error');
console.error('Error:', error);
// Reset toggle to previous state
botStatusToggle.checked = status === 'OFF' ? false : true;
});
}
function updateStyle(style) {
showLoading();
fetch('/api/update_system', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ style: style }),
})
.then(response => response.json())
.then(data => {
hideLoading();
if (data.success) {
showNotification('تم تحديث الأسلوب', 'تم تحديث أسلوب الرد بنجاح', 'success');
} else {
showNotification('خطأ', data.message, 'error');
}
})
.catch(error => {
hideLoading();
showNotification('خطأ', 'حدث خطأ أثناء تحديث الأسلوب', 'error');
console.error('Error:', error);
});
}
function openProductModal(index = -1) {
productModalTitle.textContent = index === -1 ? 'إضافة منتج جديد' : 'تعديل المنتج';
productIndex.value = index;
if (index !== -1) {
// Edit existing product
const productItem = document.querySelector(`.product-item[data-index="${index}"]`);
const productTitle = productItem.querySelector('.product-title').textContent;
const productPriceText = productItem.querySelector('.product-price').textContent;
const productDescText = productItem.querySelector('.product-description').textContent;
const productInfoElem = productItem.querySelector('.product-info');
productName.value = productTitle;
productDescription.value = productDescText;
productPrice.value = productPriceText.replace(' دينار ليبي', '');
productInfo.value = productInfoElem ? productInfoElem.textContent : '';
} else {
// Add new product
productName.value = '';
productDescription.value = '';
productPrice.value = '';
productInfo.value = '';
}
openModal(productModal);
}
function openModal(modal) {
modal.classList.add('active');
}
function closeModal(modal) {
modal.classList.remove('active');
}
function saveProduct() {
const name = productName.value.trim();
const description = productDescription.value.trim();
const price = productPrice.value.trim();
const info = productInfo.value.trim();
const index = parseInt(productIndex.value);
if (!name || !description || !price) {
showNotification('خطأ', 'يرجى ملء جميع الحقول المطلوبة', 'error');
return;
}
showLoading();
if (index === -1) {
// Add new product
fetch('/api/add_product', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
product: {
name: name,
description: description,
price: price,
info: info
}
}),
})
.then(response => response.json())
.then(data => {
hideLoading();
closeModal(productModal);
if (data.success) {
showNotification('تمت الإضافة', 'تمت إضافة المنتج بنجاح', 'success');
// Refresh the page to show the new product
setTimeout(() => {
window.location.reload();
}, 1500);
} else {
showNotification('خطأ', data.message, 'error');
}
})
.catch(error => {
hideLoading();
closeModal(productModal);
showNotification('خطأ', 'حدث خطأ أثناء إضافة المنتج', 'error');
console.error('Error:', error);
});
} else {
// First delete the old product
deleteProduct(index, false).then(() => {
// Then add the updated product
fetch('/api/add_product', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
product: {
name: name,
description: description,
price: price,
info: info
}
}),
})
.then(response => response.json())
.then(data => {
hideLoading();
closeModal(productModal);
if (data.success) {
showNotification('تم التحديث', 'تم تحديث المنتج بنجاح', 'success');
// Refresh the page to show the updated product
setTimeout(() => {
window.location.reload();
}, 1500);
} else {
showNotification('خطأ', data.message, 'error');
}
})
.catch(error => {
hideLoading();
closeModal(productModal);
showNotification('خطأ', 'حدث خطأ أثناء تحديث المنتج', 'error');
console.error('Error:', error);
});
});
}
}
function editProduct(index) {
openProductModal(index);
}
function deleteProduct(index, showConfirm = true) {
if (showConfirm && !confirm('هل أنت متأكد من حذف هذا المنتج؟')) {
return Promise.resolve();
}
showLoading();
return fetch('/api/delete_product', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ index: index }),
})
.then(response => response.json())
.then(data => {
if (showConfirm) {
hideLoading();
}
if (data.success && showConfirm) {
showNotification('تم الحذف', 'تم حذف المنتج بنجاح', 'success');
// Refresh the page to update the products list
setTimeout(() => {
window.location.reload();
}, 1500);
} else if (!data.success && showConfirm) {
showNotification('خطأ', data.message, 'error');
}
return data;
})
.catch(error => {
if (showConfirm) {
hideLoading();
showNotification('خطأ', 'حدث خطأ أثناء حذف المنتج', 'error');
console.error('Error:', error);
}
throw error;
});
}
</script>
<script>
// Logout confirmation
document.getElementById('logoutBtn').addEventListener('click', function(e) {
e.preventDefault();
// Create confirmation modal
const modalOverlay = document.createElement('div');
modalOverlay.className = 'modal-overlay';
const confirmModal = document.createElement('div');
confirmModal.className = 'confirm-modal';
confirmModal.innerHTML = `
<div class="confirm-title">تأكيد تسجيل الخروج</div>
<div class="confirm-message">هل أنت متأكد من رغبتك في تسجيل الخروج؟</div>
<div class="confirm-buttons">
<button class="btn btn-danger" id="confirmLogout">تأكيد</button>
<button class="btn btn-primary" id="cancelLogout">إلغاء</button>
</div>
`;
modalOverlay.appendChild(confirmModal);
document.body.appendChild(modalOverlay);
// Show modal
setTimeout(() => {
modalOverlay.classList.add('active');
}, 10);
// Confirm button
document.getElementById('confirmLogout').addEventListener('click', function() {
window.location.href = "{{ url_for('logout') }}";
});
// Cancel button
document.getElementById('cancelLogout').addEventListener('click', function() {
modalOverlay.classList.remove('active');
setTimeout(() => {
modalOverlay.remove();
}, 300);
});
});
// Improved delete product function
function deleteProduct(index) {
// Create confirmation modal
const modalOverlay = document.createElement('div');
modalOverlay.className = 'modal-overlay';
const confirmModal = document.createElement('div');
confirmModal.className = 'confirm-modal';
confirmModal.innerHTML = `
<div class="confirm-title">تأكيد حذف المنتج</div>
<div class="confirm-message">هل أنت متأكد من رغبتك في حذف هذا المنتج؟ لا يمكن التراجع عن هذه العملية.</div>
<div class="confirm-buttons">
<button class="btn btn-danger" id="confirmDelete">حذف</button>
<button class="btn btn-primary" id="cancelDelete">إلغاء</button>
</div>
`;
modalOverlay.appendChild(confirmModal);
document.body.appendChild(modalOverlay);
// Show modal
setTimeout(() => {
modalOverlay.classList.add('active');
}, 10);
// Confirm button
document.getElementById('confirmDelete').addEventListener('click', function() {
modalOverlay.classList.remove('active');
showLoading();
fetch('/api/delete_product', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ index: index }),
})
.then(response => response.json())
.then(data => {
hideLoading();
if (data.success) {
showNotification('تم الحذف', 'تم حذف المنتج بنجاح', 'success');
// Refresh the page to update the products list
setTimeout(() => {
window.location.reload();
}, 1500);
} else {
showNotification('خطأ', data.message, 'error');
}
setTimeout(() => {
modalOverlay.remove();
}, 300);
})
.catch(error => {
hideLoading();
showNotification('خطأ', 'حدث خطأ أثناء حذف المنتج', 'error');
console.error('Error:', error);
setTimeout(() => {
modalOverlay.remove();
}, 300);
});
});
// Cancel button
document.getElementById('cancelDelete').addEventListener('click', function() {
modalOverlay.classList.remove('active');
setTimeout(() => {
modalOverlay.remove();
}, 300);
});
}
// Improved edit product function
function editProduct(index) {
productModalTitle.textContent = 'تعديل المنتج';
productIndex.value = index;
// Get the product data from the DOM
const productItem = document.querySelector(`.product-item[data-index="${index}"]`);
if (productItem) {
const titleElem = productItem.querySelector('.product-title');
const priceElem = productItem.querySelector('.product-price');
const descElem = productItem.querySelector('.product-description');
const infoElem = productItem.querySelector('.product-info');
// Extract values
let name = titleElem ? titleElem.textContent.trim() : '';
let price = priceElem ? priceElem.textContent.replace(' دينار ليبي', '').trim() : '';
let description = descElem ? descElem.textContent.trim() : '';
let info = '';
if (infoElem) {
// Remove the label if present
info = infoElem.textContent.replace('معلومات إضافية:', '').trim();
}
// Set form values
productName.value = name;
productDescription.value = description;
productPrice.value = price;
productInfo.value = info;
}
// Open modal
openModal(productModal);
}
// Update the saveProduct function to handle editing better
function saveProduct() {
const name = productName.value.trim();
const description = productDescription.value.trim();
const price = productPrice.value.trim();
const info = productInfo.value.trim();
const index = parseInt(productIndex.value);
if (!name || !description || !price) {
showNotification('خطأ', 'يرجى ملء جميع الحقول المطلوبة', 'error');
return;
}
showLoading();
// Prepare product data
const productData = {
product: {
name: name,
description: description,
price: price,
info: info
}
};
if (index === -1) {
// Add new product
fetch('/api/add_product', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(productData),
})
.then(response => response.json())
.then(data => {
hideLoading();
closeModal(productModal);
if (data.success) {
showNotification('تمت الإضافة', 'تمت إضافة المنتج بنجاح', 'success');
// Refresh the page to show the new product
setTimeout(() => {
window.location.reload();
}, 1500);
} else {
showNotification('خطأ', data.message, 'error');
}
})
.catch(error => {
hideLoading();
closeModal(productModal);
showNotification('خطأ', 'حدث خطأ أثناء إضافة المنتج', 'error');
console.error('Error:', error);
});
} else {
// Update existing product (delete then add)
fetch('/api/delete_product', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ index: index }),
})
.then(response => response.json())
.then(data => {
if (data.success) {
// Now add the updated product
return fetch('/api/add_product', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(productData),
});
} else {
throw new Error(data.message || 'Failed to delete product');
}
})
.then(response => response.json())
.then(data => {
hideLoading();
closeModal(productModal);
if (data.success) {
showNotification('تم التحديث', 'تم تحديث المنتج بنجاح', 'success');
// Refresh the page to show the updated product
setTimeout(() => {
window.location.reload();
}, 1500);
} else {
showNotification('خطأ', data.message, 'error');
}
})
.catch(error => {
hideLoading();
closeModal(productModal);
showNotification('خطأ', 'حدث خطأ أثناء تحديث المنتج', 'error');
console.error('Error:', error);
});
}
}
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js"></script>
</body>
</html>