|
<!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;
|
|
}
|
|
|
|
|
|
::-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);
|
|
}
|
|
|
|
|
|
.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 {
|
|
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;
|
|
}
|
|
}
|
|
|
|
|
|
.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 {
|
|
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-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-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;
|
|
}
|
|
|
|
|
|
.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;
|
|
}
|
|
|
|
|
|
.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%;
|
|
}
|
|
|
|
|
|
.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 {
|
|
display: flex;
|
|
border-bottom: 1px solid var(--border-color);
|
|
margin-bottom: 20px;
|
|
overflow-x: auto;
|
|
scrollbar-width: none;
|
|
}
|
|
|
|
.tabs::-webkit-scrollbar {
|
|
display: none;
|
|
}
|
|
|
|
.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-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;
|
|
}
|
|
|
|
|
|
.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-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); }
|
|
}
|
|
|
|
|
|
.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);
|
|
}
|
|
|
|
|
|
@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 {
|
|
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 {
|
|
color: var(--danger-color);
|
|
font-weight: 500;
|
|
margin-top: 5px;
|
|
font-size: 14px;
|
|
}
|
|
|
|
|
|
.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;
|
|
}
|
|
|
|
|
|
.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;
|
|
}
|
|
|
|
.product-actions {
|
|
top: 15px;
|
|
left: 15px;
|
|
right: 15px;
|
|
justify-content: flex-end;
|
|
}
|
|
}
|
|
|
|
|
|
.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);
|
|
}
|
|
|
|
|
|
.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;
|
|
}
|
|
|
|
|
|
@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>
|
|
|
|
<div class="loading-overlay" id="loadingOverlay">
|
|
<div class="spinner"></div>
|
|
</div>
|
|
|
|
|
|
<div class="notification-container" id="notificationContainer"></div>
|
|
|
|
|
|
<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>
|
|
|
|
|
|
<div class="container">
|
|
<div class="dashboard-grid">
|
|
|
|
<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>
|
|
|
|
|
|
<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>
|
|
|
|
|
|
<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>
|
|
|
|
|
|
<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">×</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>
|
|
|
|
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');
|
|
|
|
|
|
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');
|
|
|
|
setTimeout(() => {
|
|
window.location.reload();
|
|
}, 1500);
|
|
});
|
|
|
|
socket.on('product_deleted', function(data) {
|
|
showNotification('تم الحذف', 'تم حذف المنتج بنجاح', 'success');
|
|
|
|
setTimeout(() => {
|
|
window.location.reload();
|
|
}, 1500);
|
|
});
|
|
|
|
socket.on('data_refreshed', function(data) {
|
|
showNotification('تم التحديث', 'تم تحديث البيانات بنجاح', 'info');
|
|
});
|
|
}
|
|
|
|
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
|
|
connectWebSocket();
|
|
|
|
|
|
tabItems.forEach(item => {
|
|
item.addEventListener('click', () => {
|
|
const tabId = item.getAttribute('data-tab');
|
|
|
|
|
|
tabItems.forEach(tab => tab.classList.remove('active'));
|
|
tabContents.forEach(content => content.classList.remove('active'));
|
|
|
|
|
|
item.classList.add('active');
|
|
document.getElementById(`${tabId}-tab`).classList.add('active');
|
|
});
|
|
});
|
|
|
|
|
|
botStatusToggle.addEventListener('change', function() {
|
|
updateBotStatus(this.checked ? 'ON' : 'OFF');
|
|
});
|
|
|
|
|
|
saveStyleBtn.addEventListener('click', function() {
|
|
updateStyle(styleInput.value);
|
|
});
|
|
|
|
|
|
addProductBtn.addEventListener('click', function() {
|
|
openProductModal();
|
|
});
|
|
|
|
|
|
closeProductModal.addEventListener('click', function() {
|
|
closeModal(productModal);
|
|
});
|
|
|
|
|
|
cancelProductBtn.addEventListener('click', function() {
|
|
closeModal(productModal);
|
|
});
|
|
|
|
|
|
saveProductBtn.addEventListener('click', function() {
|
|
saveProduct();
|
|
});
|
|
});
|
|
|
|
|
|
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">×</button>
|
|
`;
|
|
|
|
notificationContainer.appendChild(notification);
|
|
|
|
|
|
setTimeout(() => {
|
|
notification.classList.add('show');
|
|
}, 10);
|
|
|
|
|
|
setTimeout(() => {
|
|
closeNotification(notification);
|
|
}, 5000);
|
|
|
|
|
|
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');
|
|
|
|
botStatusToggle.checked = status === 'OFF' ? false : true;
|
|
}
|
|
})
|
|
.catch(error => {
|
|
hideLoading();
|
|
showNotification('خطأ', 'حدث خطأ أثناء تحديث الحالة', 'error');
|
|
console.error('Error:', error);
|
|
|
|
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) {
|
|
|
|
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 {
|
|
|
|
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) {
|
|
|
|
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');
|
|
|
|
setTimeout(() => {
|
|
window.location.reload();
|
|
}, 1500);
|
|
} else {
|
|
showNotification('خطأ', data.message, 'error');
|
|
}
|
|
})
|
|
.catch(error => {
|
|
hideLoading();
|
|
closeModal(productModal);
|
|
showNotification('خطأ', 'حدث خطأ أثناء إضافة المنتج', 'error');
|
|
console.error('Error:', error);
|
|
});
|
|
} else {
|
|
|
|
deleteProduct(index, false).then(() => {
|
|
|
|
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');
|
|
|
|
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');
|
|
|
|
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>
|
|
|
|
document.getElementById('logoutBtn').addEventListener('click', function(e) {
|
|
e.preventDefault();
|
|
|
|
|
|
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);
|
|
|
|
|
|
setTimeout(() => {
|
|
modalOverlay.classList.add('active');
|
|
}, 10);
|
|
|
|
|
|
document.getElementById('confirmLogout').addEventListener('click', function() {
|
|
window.location.href = "{{ url_for('logout') }}";
|
|
});
|
|
|
|
|
|
document.getElementById('cancelLogout').addEventListener('click', function() {
|
|
modalOverlay.classList.remove('active');
|
|
setTimeout(() => {
|
|
modalOverlay.remove();
|
|
}, 300);
|
|
});
|
|
});
|
|
|
|
|
|
function deleteProduct(index) {
|
|
|
|
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);
|
|
|
|
|
|
setTimeout(() => {
|
|
modalOverlay.classList.add('active');
|
|
}, 10);
|
|
|
|
|
|
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');
|
|
|
|
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);
|
|
});
|
|
});
|
|
|
|
|
|
document.getElementById('cancelDelete').addEventListener('click', function() {
|
|
modalOverlay.classList.remove('active');
|
|
setTimeout(() => {
|
|
modalOverlay.remove();
|
|
}, 300);
|
|
});
|
|
}
|
|
|
|
|
|
function editProduct(index) {
|
|
productModalTitle.textContent = 'تعديل المنتج';
|
|
productIndex.value = index;
|
|
|
|
|
|
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');
|
|
|
|
|
|
let name = titleElem ? titleElem.textContent.trim() : '';
|
|
let price = priceElem ? priceElem.textContent.replace(' دينار ليبي', '').trim() : '';
|
|
let description = descElem ? descElem.textContent.trim() : '';
|
|
let info = '';
|
|
|
|
if (infoElem) {
|
|
|
|
info = infoElem.textContent.replace('معلومات إضافية:', '').trim();
|
|
}
|
|
|
|
|
|
productName.value = name;
|
|
productDescription.value = description;
|
|
productPrice.value = price;
|
|
productInfo.value = info;
|
|
}
|
|
|
|
|
|
openModal(productModal);
|
|
}
|
|
|
|
|
|
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();
|
|
|
|
|
|
const productData = {
|
|
product: {
|
|
name: name,
|
|
description: description,
|
|
price: price,
|
|
info: info
|
|
}
|
|
};
|
|
|
|
if (index === -1) {
|
|
|
|
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');
|
|
|
|
setTimeout(() => {
|
|
window.location.reload();
|
|
}, 1500);
|
|
} else {
|
|
showNotification('خطأ', data.message, 'error');
|
|
}
|
|
})
|
|
.catch(error => {
|
|
hideLoading();
|
|
closeModal(productModal);
|
|
showNotification('خطأ', 'حدث خطأ أثناء إضافة المنتج', 'error');
|
|
console.error('Error:', error);
|
|
});
|
|
} else {
|
|
|
|
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) {
|
|
|
|
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');
|
|
|
|
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> |