createsonline 0.1.26__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- createsonline/__init__.py +46 -0
- createsonline/admin/__init__.py +7 -0
- createsonline/admin/content.py +526 -0
- createsonline/admin/crud.py +805 -0
- createsonline/admin/field_builder.py +559 -0
- createsonline/admin/integration.py +482 -0
- createsonline/admin/interface.py +2562 -0
- createsonline/admin/model_creator.py +513 -0
- createsonline/admin/model_manager.py +388 -0
- createsonline/admin/modern_dashboard.py +498 -0
- createsonline/admin/permissions.py +264 -0
- createsonline/admin/user_forms.py +594 -0
- createsonline/ai/__init__.py +202 -0
- createsonline/ai/fields.py +1226 -0
- createsonline/ai/orm.py +325 -0
- createsonline/ai/services.py +1244 -0
- createsonline/app.py +506 -0
- createsonline/auth/__init__.py +8 -0
- createsonline/auth/management.py +228 -0
- createsonline/auth/models.py +552 -0
- createsonline/cli/__init__.py +5 -0
- createsonline/cli/commands/__init__.py +122 -0
- createsonline/cli/commands/database.py +416 -0
- createsonline/cli/commands/info.py +173 -0
- createsonline/cli/commands/initdb.py +218 -0
- createsonline/cli/commands/project.py +545 -0
- createsonline/cli/commands/serve.py +173 -0
- createsonline/cli/commands/shell.py +93 -0
- createsonline/cli/commands/users.py +148 -0
- createsonline/cli/main.py +2041 -0
- createsonline/cli/manage.py +274 -0
- createsonline/config/__init__.py +9 -0
- createsonline/config/app.py +2577 -0
- createsonline/config/database.py +179 -0
- createsonline/config/docs.py +384 -0
- createsonline/config/errors.py +160 -0
- createsonline/config/orm.py +43 -0
- createsonline/config/request.py +93 -0
- createsonline/config/settings.py +176 -0
- createsonline/data/__init__.py +23 -0
- createsonline/data/dataframe.py +925 -0
- createsonline/data/io.py +453 -0
- createsonline/data/series.py +557 -0
- createsonline/database/__init__.py +60 -0
- createsonline/database/abstraction.py +440 -0
- createsonline/database/assistant.py +585 -0
- createsonline/database/fields.py +442 -0
- createsonline/database/migrations.py +132 -0
- createsonline/database/models.py +604 -0
- createsonline/database.py +438 -0
- createsonline/http/__init__.py +28 -0
- createsonline/http/client.py +535 -0
- createsonline/ml/__init__.py +55 -0
- createsonline/ml/classification.py +552 -0
- createsonline/ml/clustering.py +680 -0
- createsonline/ml/metrics.py +542 -0
- createsonline/ml/neural.py +560 -0
- createsonline/ml/preprocessing.py +784 -0
- createsonline/ml/regression.py +501 -0
- createsonline/performance/__init__.py +19 -0
- createsonline/performance/cache.py +444 -0
- createsonline/performance/compression.py +335 -0
- createsonline/performance/core.py +419 -0
- createsonline/project_init.py +789 -0
- createsonline/routing.py +528 -0
- createsonline/security/__init__.py +34 -0
- createsonline/security/core.py +811 -0
- createsonline/security/encryption.py +349 -0
- createsonline/server.py +295 -0
- createsonline/static/css/admin.css +263 -0
- createsonline/static/css/common.css +358 -0
- createsonline/static/css/dashboard.css +89 -0
- createsonline/static/favicon.ico +0 -0
- createsonline/static/icons/icon-128x128.png +0 -0
- createsonline/static/icons/icon-128x128.webp +0 -0
- createsonline/static/icons/icon-16x16.png +0 -0
- createsonline/static/icons/icon-16x16.webp +0 -0
- createsonline/static/icons/icon-180x180.png +0 -0
- createsonline/static/icons/icon-180x180.webp +0 -0
- createsonline/static/icons/icon-192x192.png +0 -0
- createsonline/static/icons/icon-192x192.webp +0 -0
- createsonline/static/icons/icon-256x256.png +0 -0
- createsonline/static/icons/icon-256x256.webp +0 -0
- createsonline/static/icons/icon-32x32.png +0 -0
- createsonline/static/icons/icon-32x32.webp +0 -0
- createsonline/static/icons/icon-384x384.png +0 -0
- createsonline/static/icons/icon-384x384.webp +0 -0
- createsonline/static/icons/icon-48x48.png +0 -0
- createsonline/static/icons/icon-48x48.webp +0 -0
- createsonline/static/icons/icon-512x512.png +0 -0
- createsonline/static/icons/icon-512x512.webp +0 -0
- createsonline/static/icons/icon-64x64.png +0 -0
- createsonline/static/icons/icon-64x64.webp +0 -0
- createsonline/static/image/android-chrome-192x192.png +0 -0
- createsonline/static/image/android-chrome-512x512.png +0 -0
- createsonline/static/image/apple-touch-icon.png +0 -0
- createsonline/static/image/favicon-16x16.png +0 -0
- createsonline/static/image/favicon-32x32.png +0 -0
- createsonline/static/image/favicon.ico +0 -0
- createsonline/static/image/favicon.svg +17 -0
- createsonline/static/image/icon-128x128.png +0 -0
- createsonline/static/image/icon-128x128.webp +0 -0
- createsonline/static/image/icon-16x16.png +0 -0
- createsonline/static/image/icon-16x16.webp +0 -0
- createsonline/static/image/icon-180x180.png +0 -0
- createsonline/static/image/icon-180x180.webp +0 -0
- createsonline/static/image/icon-192x192.png +0 -0
- createsonline/static/image/icon-192x192.webp +0 -0
- createsonline/static/image/icon-256x256.png +0 -0
- createsonline/static/image/icon-256x256.webp +0 -0
- createsonline/static/image/icon-32x32.png +0 -0
- createsonline/static/image/icon-32x32.webp +0 -0
- createsonline/static/image/icon-384x384.png +0 -0
- createsonline/static/image/icon-384x384.webp +0 -0
- createsonline/static/image/icon-48x48.png +0 -0
- createsonline/static/image/icon-48x48.webp +0 -0
- createsonline/static/image/icon-512x512.png +0 -0
- createsonline/static/image/icon-512x512.webp +0 -0
- createsonline/static/image/icon-64x64.png +0 -0
- createsonline/static/image/icon-64x64.webp +0 -0
- createsonline/static/image/logo-header-h100.png +0 -0
- createsonline/static/image/logo-header-h100.webp +0 -0
- createsonline/static/image/logo-header-h200@2x.png +0 -0
- createsonline/static/image/logo-header-h200@2x.webp +0 -0
- createsonline/static/image/logo.png +0 -0
- createsonline/static/js/admin.js +274 -0
- createsonline/static/site.webmanifest +35 -0
- createsonline/static/templates/admin/base.html +87 -0
- createsonline/static/templates/admin/dashboard.html +217 -0
- createsonline/static/templates/admin/model_form.html +270 -0
- createsonline/static/templates/admin/model_list.html +202 -0
- createsonline/static/test_script.js +15 -0
- createsonline/static/test_styles.css +59 -0
- createsonline/static_files.py +365 -0
- createsonline/templates/404.html +100 -0
- createsonline/templates/admin_login.html +169 -0
- createsonline/templates/base.html +102 -0
- createsonline/templates/index.html +151 -0
- createsonline/templates.py +205 -0
- createsonline/testing.py +322 -0
- createsonline/utils.py +448 -0
- createsonline/validation/__init__.py +49 -0
- createsonline/validation/fields.py +598 -0
- createsonline/validation/models.py +504 -0
- createsonline/validation/validators.py +561 -0
- createsonline/views.py +184 -0
- createsonline-0.1.26.dist-info/METADATA +46 -0
- createsonline-0.1.26.dist-info/RECORD +152 -0
- createsonline-0.1.26.dist-info/WHEEL +5 -0
- createsonline-0.1.26.dist-info/entry_points.txt +2 -0
- createsonline-0.1.26.dist-info/licenses/LICENSE +21 -0
- createsonline-0.1.26.dist-info/top_level.txt +1 -0
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<defs>
|
|
3
|
+
<style>
|
|
4
|
+
.brand-text {
|
|
5
|
+
font-family: 'Inter', 'Segoe UI', Arial, sans-serif;
|
|
6
|
+
font-weight: 800;
|
|
7
|
+
font-size: 18px;
|
|
8
|
+
fill: #111;
|
|
9
|
+
}
|
|
10
|
+
</style>
|
|
11
|
+
</defs>
|
|
12
|
+
<!-- Background -->
|
|
13
|
+
<rect width="32" height="32" rx="6" fill="#fafafa"/>
|
|
14
|
+
|
|
15
|
+
<!-- Brand Symbol C⎯● -->
|
|
16
|
+
<text x="16" y="22" text-anchor="middle" class="brand-text">C⎯●</text>
|
|
17
|
+
</svg>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
// CREATESONLINE Admin Panel JavaScript v0.1.6
|
|
2
|
+
|
|
3
|
+
class CreatesonlineAdmin {
|
|
4
|
+
constructor() {
|
|
5
|
+
this.init();
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
init() {
|
|
9
|
+
this.setupNavigation();
|
|
10
|
+
this.setupForms();
|
|
11
|
+
this.setupTables();
|
|
12
|
+
this.setupModals();
|
|
13
|
+
this.setupNotifications();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
setupNavigation() {
|
|
17
|
+
// Sidebar toggle for mobile
|
|
18
|
+
const toggle = document.getElementById('sidebar-toggle');
|
|
19
|
+
const sidebar = document.querySelector('.admin-sidebar');
|
|
20
|
+
|
|
21
|
+
if (toggle && sidebar) {
|
|
22
|
+
toggle.addEventListener('click', () => {
|
|
23
|
+
sidebar.classList.toggle('active');
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Active menu item
|
|
28
|
+
const currentPath = window.location.pathname;
|
|
29
|
+
document.querySelectorAll('.admin-sidebar li').forEach(item => {
|
|
30
|
+
if (item.dataset.path === currentPath) {
|
|
31
|
+
item.classList.add('active');
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
setupForms() {
|
|
37
|
+
// Form validation
|
|
38
|
+
document.querySelectorAll('.admin-form').forEach(form => {
|
|
39
|
+
form.addEventListener('submit', (e) => {
|
|
40
|
+
if (!this.validateForm(form)) {
|
|
41
|
+
e.preventDefault();
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// Auto-save functionality
|
|
47
|
+
document.querySelectorAll('[data-autosave]').forEach(input => {
|
|
48
|
+
let timeout;
|
|
49
|
+
input.addEventListener('input', () => {
|
|
50
|
+
clearTimeout(timeout);
|
|
51
|
+
timeout = setTimeout(() => this.autoSave(input), 1000);
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
validateForm(form) {
|
|
57
|
+
let isValid = true;
|
|
58
|
+
const inputs = form.querySelectorAll('[required]');
|
|
59
|
+
|
|
60
|
+
inputs.forEach(input => {
|
|
61
|
+
if (!input.value.trim()) {
|
|
62
|
+
this.showError(input, 'This field is required');
|
|
63
|
+
isValid = false;
|
|
64
|
+
} else {
|
|
65
|
+
this.clearError(input);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
return isValid;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
showError(input, message) {
|
|
73
|
+
const error = input.nextElementSibling;
|
|
74
|
+
if (error && error.classList.contains('error-message')) {
|
|
75
|
+
error.textContent = message;
|
|
76
|
+
} else {
|
|
77
|
+
const errorEl = document.createElement('span');
|
|
78
|
+
errorEl.className = 'error-message';
|
|
79
|
+
errorEl.textContent = message;
|
|
80
|
+
errorEl.style.color = '#ef4444';
|
|
81
|
+
errorEl.style.fontSize = '0.875rem';
|
|
82
|
+
input.parentNode.insertBefore(errorEl, input.nextSibling);
|
|
83
|
+
}
|
|
84
|
+
input.style.borderColor = '#ef4444';
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
clearError(input) {
|
|
88
|
+
const error = input.nextElementSibling;
|
|
89
|
+
if (error && error.classList.contains('error-message')) {
|
|
90
|
+
error.remove();
|
|
91
|
+
}
|
|
92
|
+
input.style.borderColor = '';
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
setupTables() {
|
|
96
|
+
// Sortable tables
|
|
97
|
+
document.querySelectorAll('.admin-table th[data-sort]').forEach(header => {
|
|
98
|
+
header.style.cursor = 'pointer';
|
|
99
|
+
header.addEventListener('click', () => {
|
|
100
|
+
this.sortTable(header);
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// Row selection
|
|
105
|
+
document.querySelectorAll('.admin-table input[type="checkbox"]').forEach(checkbox => {
|
|
106
|
+
checkbox.addEventListener('change', (e) => {
|
|
107
|
+
const row = e.target.closest('tr');
|
|
108
|
+
row.classList.toggle('selected', e.target.checked);
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
// Bulk actions
|
|
113
|
+
const bulkSelect = document.getElementById('bulk-select');
|
|
114
|
+
if (bulkSelect) {
|
|
115
|
+
bulkSelect.addEventListener('change', (e) => {
|
|
116
|
+
const checkboxes = document.querySelectorAll('.admin-table tbody input[type="checkbox"]');
|
|
117
|
+
checkboxes.forEach(cb => {
|
|
118
|
+
cb.checked = e.target.checked;
|
|
119
|
+
cb.closest('tr').classList.toggle('selected', e.target.checked);
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
sortTable(header) {
|
|
126
|
+
const table = header.closest('table');
|
|
127
|
+
const tbody = table.querySelector('tbody');
|
|
128
|
+
const rows = Array.from(tbody.querySelectorAll('tr'));
|
|
129
|
+
const column = Array.from(header.parentNode.children).indexOf(header);
|
|
130
|
+
const isAscending = header.classList.contains('sort-asc');
|
|
131
|
+
|
|
132
|
+
rows.sort((a, b) => {
|
|
133
|
+
const aValue = a.children[column].textContent.trim();
|
|
134
|
+
const bValue = b.children[column].textContent.trim();
|
|
135
|
+
|
|
136
|
+
if (!isNaN(aValue) && !isNaN(bValue)) {
|
|
137
|
+
return isAscending ? aValue - bValue : bValue - aValue;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return isAscending
|
|
141
|
+
? aValue.localeCompare(bValue)
|
|
142
|
+
: bValue.localeCompare(aValue);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
rows.forEach(row => tbody.appendChild(row));
|
|
146
|
+
|
|
147
|
+
// Toggle sort direction
|
|
148
|
+
header.classList.toggle('sort-asc', !isAscending);
|
|
149
|
+
header.classList.toggle('sort-desc', isAscending);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
setupModals() {
|
|
153
|
+
// Open modal
|
|
154
|
+
document.querySelectorAll('[data-modal]').forEach(trigger => {
|
|
155
|
+
trigger.addEventListener('click', (e) => {
|
|
156
|
+
e.preventDefault();
|
|
157
|
+
const modalId = trigger.dataset.modal;
|
|
158
|
+
const modal = document.getElementById(modalId);
|
|
159
|
+
if (modal) {
|
|
160
|
+
modal.classList.add('active');
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
// Close modal
|
|
166
|
+
document.querySelectorAll('.modal-close, .modal-backdrop').forEach(close => {
|
|
167
|
+
close.addEventListener('click', () => {
|
|
168
|
+
close.closest('.modal').classList.remove('active');
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
setupNotifications() {
|
|
174
|
+
// Auto-dismiss notifications
|
|
175
|
+
document.querySelectorAll('.admin-notification').forEach(notification => {
|
|
176
|
+
setTimeout(() => {
|
|
177
|
+
notification.style.opacity = '0';
|
|
178
|
+
setTimeout(() => notification.remove(), 300);
|
|
179
|
+
}, 5000);
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
autoSave(input) {
|
|
184
|
+
const data = {
|
|
185
|
+
field: input.name,
|
|
186
|
+
value: input.value
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
fetch('/admin/autosave', {
|
|
190
|
+
method: 'POST',
|
|
191
|
+
headers: {
|
|
192
|
+
'Content-Type': 'application/json',
|
|
193
|
+
},
|
|
194
|
+
body: JSON.stringify(data)
|
|
195
|
+
})
|
|
196
|
+
.then(response => response.json())
|
|
197
|
+
.then(data => {
|
|
198
|
+
this.showNotification('Auto-saved', 'success');
|
|
199
|
+
})
|
|
200
|
+
.catch(error => {
|
|
201
|
+
console.error('Auto-save failed:', error);
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
showNotification(message, type = 'info') {
|
|
206
|
+
const notification = document.createElement('div');
|
|
207
|
+
notification.className = `admin-notification admin-notification-${type}`;
|
|
208
|
+
notification.textContent = message;
|
|
209
|
+
notification.style.cssText = `
|
|
210
|
+
position: fixed;
|
|
211
|
+
top: 20px;
|
|
212
|
+
right: 20px;
|
|
213
|
+
padding: 1rem 1.5rem;
|
|
214
|
+
background: ${type === 'success' ? '#10b981' : '#2563eb'};
|
|
215
|
+
color: white;
|
|
216
|
+
border-radius: 4px;
|
|
217
|
+
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
|
|
218
|
+
z-index: 10000;
|
|
219
|
+
transition: opacity 0.3s;
|
|
220
|
+
`;
|
|
221
|
+
|
|
222
|
+
document.body.appendChild(notification);
|
|
223
|
+
|
|
224
|
+
setTimeout(() => {
|
|
225
|
+
notification.style.opacity = '0';
|
|
226
|
+
setTimeout(() => notification.remove(), 300);
|
|
227
|
+
}, 3000);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// API Methods
|
|
231
|
+
async fetchData(endpoint) {
|
|
232
|
+
try {
|
|
233
|
+
const response = await fetch(endpoint);
|
|
234
|
+
return await response.json();
|
|
235
|
+
} catch (error) {
|
|
236
|
+
this.showNotification('Failed to fetch data', 'error');
|
|
237
|
+
throw error;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
async saveData(endpoint, data) {
|
|
242
|
+
try {
|
|
243
|
+
const response = await fetch(endpoint, {
|
|
244
|
+
method: 'POST',
|
|
245
|
+
headers: {
|
|
246
|
+
'Content-Type': 'application/json',
|
|
247
|
+
},
|
|
248
|
+
body: JSON.stringify(data)
|
|
249
|
+
});
|
|
250
|
+
return await response.json();
|
|
251
|
+
} catch (error) {
|
|
252
|
+
this.showNotification('Failed to save data', 'error');
|
|
253
|
+
throw error;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
async deleteData(endpoint) {
|
|
258
|
+
try {
|
|
259
|
+
const response = await fetch(endpoint, {
|
|
260
|
+
method: 'DELETE'
|
|
261
|
+
});
|
|
262
|
+
return await response.json();
|
|
263
|
+
} catch (error) {
|
|
264
|
+
this.showNotification('Failed to delete data', 'error');
|
|
265
|
+
throw error;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// Initialize admin panel when DOM is ready
|
|
271
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
272
|
+
window.adminPanel = new CreatesonlineAdmin();
|
|
273
|
+
console.log('CREATESONLINE Admin Panel v0.1.6 initialized');
|
|
274
|
+
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "CREATESONLINE Framework",
|
|
3
|
+
"short_name": "CREATESONLINE",
|
|
4
|
+
"description": "AI-Native Web Framework with Pure Independence",
|
|
5
|
+
"start_url": "/",
|
|
6
|
+
"display": "standalone",
|
|
7
|
+
"background_color": "#667eea",
|
|
8
|
+
"theme_color": "#667eea",
|
|
9
|
+
"icons": [
|
|
10
|
+
{
|
|
11
|
+
"src": "/static/icons/icon-192x192.png",
|
|
12
|
+
"sizes": "192x192",
|
|
13
|
+
"type": "image/png",
|
|
14
|
+
"purpose": "any maskable"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"src": "/static/icons/icon-512x512.png",
|
|
18
|
+
"sizes": "512x512",
|
|
19
|
+
"type": "image/png",
|
|
20
|
+
"purpose": "any maskable"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"src": "/static/icons/icon-192x192.webp",
|
|
24
|
+
"sizes": "192x192",
|
|
25
|
+
"type": "image/webp",
|
|
26
|
+
"purpose": "any maskable"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"src": "/static/icons/icon-512x512.webp",
|
|
30
|
+
"sizes": "512x512",
|
|
31
|
+
"type": "image/webp",
|
|
32
|
+
"purpose": "any maskable"
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>{% block title %}CREATESONLINE Admin{% endblock %}</title>
|
|
7
|
+
<link rel="stylesheet" href="/static/css/admin.css">
|
|
8
|
+
{% block extra_css %}{% endblock %}
|
|
9
|
+
</head>
|
|
10
|
+
<body>
|
|
11
|
+
<div class="admin-container">
|
|
12
|
+
<!-- Header -->
|
|
13
|
+
<header class="admin-header">
|
|
14
|
+
<div class="header-brand">
|
|
15
|
+
<h1>CREATESONLINE</h1>
|
|
16
|
+
<span class="badge badge-primary">v0.1.6</span>
|
|
17
|
+
</div>
|
|
18
|
+
<div class="header-actions">
|
|
19
|
+
<span class="user-info">Admin Panel</span>
|
|
20
|
+
<button class="btn btn-sm" onclick="window.location.href='/admin/logout'">Logout</button>
|
|
21
|
+
</div>
|
|
22
|
+
</header>
|
|
23
|
+
|
|
24
|
+
<div class="admin-layout">
|
|
25
|
+
<!-- Sidebar -->
|
|
26
|
+
<aside class="admin-sidebar">
|
|
27
|
+
<nav class="sidebar-nav">
|
|
28
|
+
<div class="nav-section">
|
|
29
|
+
<h3 class="nav-section-title">Dashboard</h3>
|
|
30
|
+
<ul class="nav-menu">
|
|
31
|
+
<li class="nav-item">
|
|
32
|
+
<a href="/admin/" class="nav-link {% if request.path == '/admin/' %}active{% endif %}">
|
|
33
|
+
<span class="nav-icon">🏠</span>
|
|
34
|
+
<span class="nav-text">Home</span>
|
|
35
|
+
</a>
|
|
36
|
+
</li>
|
|
37
|
+
</ul>
|
|
38
|
+
</div>
|
|
39
|
+
|
|
40
|
+
<div class="nav-section">
|
|
41
|
+
<h3 class="nav-section-title">Models</h3>
|
|
42
|
+
<ul class="nav-menu">
|
|
43
|
+
{% block sidebar_menu %}
|
|
44
|
+
<!-- Model links will be inserted here -->
|
|
45
|
+
{% endblock %}
|
|
46
|
+
</ul>
|
|
47
|
+
</div>
|
|
48
|
+
|
|
49
|
+
<div class="nav-section">
|
|
50
|
+
<h3 class="nav-section-title">System</h3>
|
|
51
|
+
<ul class="nav-menu">
|
|
52
|
+
<li class="nav-item">
|
|
53
|
+
<a href="/admin/settings" class="nav-link">
|
|
54
|
+
<span class="nav-icon">⚙️</span>
|
|
55
|
+
<span class="nav-text">Settings</span>
|
|
56
|
+
</a>
|
|
57
|
+
</li>
|
|
58
|
+
</ul>
|
|
59
|
+
</div>
|
|
60
|
+
</nav>
|
|
61
|
+
</aside>
|
|
62
|
+
|
|
63
|
+
<!-- Main Content -->
|
|
64
|
+
<main class="admin-main">
|
|
65
|
+
{% block breadcrumbs %}
|
|
66
|
+
<div class="breadcrumbs">
|
|
67
|
+
<a href="/admin/">Home</a>
|
|
68
|
+
</div>
|
|
69
|
+
{% endblock %}
|
|
70
|
+
|
|
71
|
+
{% block messages %}
|
|
72
|
+
<!-- Messages will be displayed here -->
|
|
73
|
+
{% endblock %}
|
|
74
|
+
|
|
75
|
+
<div class="admin-content">
|
|
76
|
+
{% block content %}
|
|
77
|
+
<!-- Main content goes here -->
|
|
78
|
+
{% endblock %}
|
|
79
|
+
</div>
|
|
80
|
+
</main>
|
|
81
|
+
</div>
|
|
82
|
+
</div>
|
|
83
|
+
|
|
84
|
+
<script src="/static/js/admin.js"></script>
|
|
85
|
+
{% block extra_js %}{% endblock %}
|
|
86
|
+
</body>
|
|
87
|
+
</html>
|