mirror of
https://github.com/narrrl/holy-flavor-rater.git
synced 2026-11-03 16:41:27 +01:00
Merge branch 'main' into narl.io
This commit is contained in:
commit
673872c931
2 files changed
+73
-51
No files matched your search
@@ -5,12 +5,16 @@ from rest_framework.authtoken.views import obtain_auth_token
|
||||
from django.conf import settings
|
||||
from django.conf.urls.static import static
|
||||
from django.views.static import serve
|
||||
from django.views.generic.base import TemplateView
|
||||
from django.views.static import serve
|
||||
from django.conf import settings
|
||||
import os
|
||||
|
||||
# Clean the admin path
|
||||
admin_url = os.environ.get('ADMIN_URL', 'admin').strip('/')
|
||||
|
||||
def serve_index(request, resource=None):
|
||||
return serve(request, 'index.html', document_root=settings.STATIC_ROOT)
|
||||
|
||||
urlpatterns = [
|
||||
# Robots.txt
|
||||
path('robots.txt', TemplateView.as_view(template_name="robots.txt", content_type="text/plain")),
|
||||
@@ -24,4 +28,8 @@ urlpatterns = [
|
||||
path('api/schema/swagger-ui/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'),
|
||||
path('api/schema/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'),
|
||||
path('media/<path:path>', serve, {'document_root': settings.MEDIA_ROOT}),
|
||||
|
||||
# Catch-all for React Frontend
|
||||
path('', serve_index, name='index'),
|
||||
path('<path:resource>', serve_index),
|
||||
]
|
||||
@@ -274,57 +274,71 @@ const AdminDashboard: React.FC = () => {
|
||||
{currentTab === 2 && (
|
||||
<Box>
|
||||
<Typography variant="h5" sx={{ fontWeight: 'bold', mb: 3 }}>{t('admin.banners')}</Typography>
|
||||
<Grid container spacing={3}>
|
||||
{banners.map((banner) => (
|
||||
<Grid size={{ xs: 12, md: 4 }} key={banner.id}>
|
||||
<Card sx={{ borderRadius: 3, position: 'relative', height: '100%', display: 'flex', flexDirection: 'column' }}>
|
||||
{banner.is_active && (
|
||||
<Chip
|
||||
icon={<CheckCircleIcon />}
|
||||
label="Active"
|
||||
color="success"
|
||||
size="small"
|
||||
sx={{ position: 'absolute', top: 12, right: 12, zIndex: 2 }}
|
||||
/>
|
||||
)}
|
||||
<CardContent sx={{ flexGrow: 1 }}>
|
||||
<Typography variant="h6" sx={{ fontWeight: 'bold', mb: 1 }}>{banner.name}</Typography>
|
||||
<Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>{banner.description}</Typography>
|
||||
|
||||
<Box sx={{ mt: 2, p: 2, bgcolor: 'action.hover', borderRadius: 2 }}>
|
||||
<Typography variant="caption" sx={{ fontWeight: 'bold', display: 'block', mb: 1 }}>Settings:</Typography>
|
||||
<pre style={{ margin: 0, fontSize: '0.7rem', overflow: 'auto' }}>
|
||||
{JSON.stringify(banner.settings, null, 2)}
|
||||
</pre>
|
||||
|
||||
{banners.length === 0 ? (
|
||||
<Card variant="outlined" sx={{ p: 4, textAlign: 'center', borderRadius: 3 }}>
|
||||
<Typography color="text.secondary">No banner models found in the database.</Typography>
|
||||
<Button
|
||||
variant="outlined"
|
||||
sx={{ mt: 2 }}
|
||||
onClick={fetchData}
|
||||
>
|
||||
Retry Loading
|
||||
</Button>
|
||||
</Card>
|
||||
) : (
|
||||
<Grid container spacing={3}>
|
||||
{banners.map((banner) => (
|
||||
<Grid size={{ xs: 12, md: 4 }} key={banner.id}>
|
||||
<Card sx={{ borderRadius: 3, position: 'relative', height: '100%', display: 'flex', flexDirection: 'column' }}>
|
||||
{banner.is_active && (
|
||||
<Chip
|
||||
icon={<CheckCircleIcon />}
|
||||
label="Active"
|
||||
color="success"
|
||||
size="small"
|
||||
sx={{ position: 'absolute', top: 12, right: 12, zIndex: 2 }}
|
||||
/>
|
||||
)}
|
||||
<CardContent sx={{ flexGrow: 1 }}>
|
||||
<Typography variant="h6" sx={{ fontWeight: 'bold', mb: 1 }}>{banner.name}</Typography>
|
||||
<Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>{banner.description}</Typography>
|
||||
|
||||
<Box sx={{ mt: 2, p: 2, bgcolor: 'action.hover', borderRadius: 2 }}>
|
||||
<Typography variant="caption" sx={{ fontWeight: 'bold', display: 'block', mb: 1 }}>Settings:</Typography>
|
||||
<pre style={{ margin: 0, fontSize: '0.7rem', overflow: 'auto' }}>
|
||||
{JSON.stringify(banner.settings, null, 2)}
|
||||
</pre>
|
||||
</Box>
|
||||
</CardContent>
|
||||
<Box sx={{ p: 2, pt: 0 }}>
|
||||
<Stack direction="row" spacing={1}>
|
||||
<Button
|
||||
fullWidth
|
||||
variant="outlined"
|
||||
startIcon={<EditIcon />}
|
||||
onClick={() => {
|
||||
setSelectedBanner(banner);
|
||||
setIsSettingsDialogOpen(true);
|
||||
}}
|
||||
>
|
||||
Edit Settings
|
||||
</Button>
|
||||
<Button
|
||||
fullWidth
|
||||
variant={banner.is_active ? "outlined" : "contained"}
|
||||
disabled={banner.is_active}
|
||||
onClick={() => handleActivateBanner(banner.id)}
|
||||
>
|
||||
{banner.is_active ? "Currently Active" : "Set as Active"}
|
||||
</Button>
|
||||
</Stack>
|
||||
</Box>
|
||||
</CardContent>
|
||||
<Box sx={{ p: 2, pt: 0 }}>
|
||||
<Stack direction="row" spacing={1}>
|
||||
<Button
|
||||
fullWidth
|
||||
variant="outlined"
|
||||
startIcon={<EditIcon />}
|
||||
onClick={() => {
|
||||
setSelectedBanner(banner);
|
||||
setIsSettingsDialogOpen(true);
|
||||
}}
|
||||
>
|
||||
Edit Settings
|
||||
</Button>
|
||||
<Button
|
||||
fullWidth
|
||||
variant={banner.is_active ? "outlined" : "contained"}
|
||||
disabled={banner.is_active}
|
||||
onClick={() => handleActivateBanner(banner.id)}
|
||||
>
|
||||
{banner.is_active ? "Currently Active" : "Set as Active"}
|
||||
</Button>
|
||||
</Stack>
|
||||
</Box>
|
||||
</Card>
|
||||
</Grid>
|
||||
))}
|
||||
</Grid>
|
||||
</Card>
|
||||
</Grid>
|
||||
))}
|
||||
</Grid>
|
||||
)}
|
||||
</Box>
|
||||
)}
|
||||
|
||||
|
||||
Reference in new issue
Block a user