nice
This commit is contained in:
parent
29eacb2578
commit
7875f21b4d
@ -13,11 +13,16 @@ class UsersConfig(AppConfig):
|
|||||||
# Only run when the server is actually starting
|
# Only run when the server is actually starting
|
||||||
if 'runserver' in sys.argv:
|
if 'runserver' in sys.argv:
|
||||||
try:
|
try:
|
||||||
# Import here to avoid issues during Django startup
|
|
||||||
from .models import User
|
from .models import User
|
||||||
from decouple import config
|
from decouple import config
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
|
|
||||||
|
# Don't create/synchronize the configured admin if another
|
||||||
|
# superuser already exists.
|
||||||
|
if User.objects.filter(is_superuser=True).exists():
|
||||||
|
print('A superuser already exists; no admin user was created.')
|
||||||
|
return
|
||||||
|
|
||||||
username = config('ADMIN_USERNAME', default='').strip()
|
username = config('ADMIN_USERNAME', default='').strip()
|
||||||
password = config('ADMIN_PASSWORD', default='')
|
password = config('ADMIN_PASSWORD', default='')
|
||||||
first_name = config('ADMIN_FIRST_NAME', default='').strip()
|
first_name = config('ADMIN_FIRST_NAME', default='').strip()
|
||||||
@ -50,6 +55,7 @@ class UsersConfig(AppConfig):
|
|||||||
|
|
||||||
action = 'created' if created else 'synchronized'
|
action = 'created' if created else 'synchronized'
|
||||||
print(f'Admin user "{username}" {action}.')
|
print(f'Admin user "{username}" {action}.')
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# Don't fail the entire Django startup if there's an error
|
# Don't fail the entire Django startup if there's an error
|
||||||
print(f'Error creating admin user: {e}')
|
print(f'Error creating admin user: {e}')
|
||||||
|
|||||||
@ -8,7 +8,6 @@ import {
|
|||||||
SidebarFooter,
|
SidebarFooter,
|
||||||
SidebarGroup,
|
SidebarGroup,
|
||||||
SidebarGroupContent,
|
SidebarGroupContent,
|
||||||
SidebarGroupLabel,
|
|
||||||
SidebarHeader,
|
SidebarHeader,
|
||||||
SidebarMenu,
|
SidebarMenu,
|
||||||
SidebarMenuButton,
|
SidebarMenuButton,
|
||||||
@ -86,6 +85,82 @@ const NavBar = () => {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hauteur d'une ligne de navigation.
|
||||||
|
*
|
||||||
|
* Le SidebarMenuButton natif fait 32px.
|
||||||
|
* On lui donne une ligne de 48px et on le centre.
|
||||||
|
*
|
||||||
|
* Le header de groupe fait lui aussi 32px.
|
||||||
|
* En mode plié, il est remplacé visuellement par
|
||||||
|
* une séparation, mais conserve exactement ses 32px.
|
||||||
|
*/
|
||||||
|
const menuItemClass = 'h-12 min-h-12 flex items-center';
|
||||||
|
|
||||||
|
const buttonClass = `
|
||||||
|
w-full
|
||||||
|
h-8
|
||||||
|
min-h-8
|
||||||
|
group-data-[collapsible=icon]:size-8!
|
||||||
|
group-data-[collapsible=icon]:p-2!
|
||||||
|
`;
|
||||||
|
|
||||||
|
const linkClass = `
|
||||||
|
flex
|
||||||
|
h-full
|
||||||
|
w-full
|
||||||
|
items-center
|
||||||
|
gap-2
|
||||||
|
text-base
|
||||||
|
`;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Header de groupe :
|
||||||
|
*
|
||||||
|
* Déplié :
|
||||||
|
* [ Navigation ] 32px
|
||||||
|
*
|
||||||
|
* Plié :
|
||||||
|
* [ ---------------------- ] 32px
|
||||||
|
*
|
||||||
|
* Même hauteur dans les deux cas.
|
||||||
|
*/
|
||||||
|
const GroupHeader = ({ children }) => (
|
||||||
|
<div
|
||||||
|
className="
|
||||||
|
flex
|
||||||
|
h-8
|
||||||
|
min-h-8
|
||||||
|
w-full
|
||||||
|
items-center
|
||||||
|
px-2
|
||||||
|
"
|
||||||
|
>
|
||||||
|
{/* Nom du groupe */}
|
||||||
|
<span
|
||||||
|
className="
|
||||||
|
truncate
|
||||||
|
text-lg
|
||||||
|
font-medium
|
||||||
|
group-data-[collapsible=icon]:hidden
|
||||||
|
"
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
{/* Séparation en mode plié */}
|
||||||
|
<div
|
||||||
|
className="
|
||||||
|
hidden
|
||||||
|
w-full
|
||||||
|
border-t
|
||||||
|
border-sidebar-border
|
||||||
|
group-data-[collapsible=icon]:block
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Sidebar
|
<Sidebar
|
||||||
className="border-0"
|
className="border-0"
|
||||||
@ -94,13 +169,18 @@ const NavBar = () => {
|
|||||||
onMouseLeave={handleMouseLeave}
|
onMouseLeave={handleMouseLeave}
|
||||||
>
|
>
|
||||||
{/* Logo / nom de la boulangerie */}
|
{/* Logo / nom de la boulangerie */}
|
||||||
<SidebarHeader>
|
<SidebarHeader className="h-16 p-2 pl-0">
|
||||||
<SidebarMenu>
|
<SidebarMenu>
|
||||||
<SidebarMenuItem>
|
<SidebarMenuItem className="h-12 flex items-center">
|
||||||
<SidebarMenuButton
|
<SidebarMenuButton
|
||||||
size="lg"
|
size="lg"
|
||||||
tooltip="Le Fournil du Bocage"
|
className="
|
||||||
onClick={handleCloseMenu}
|
h-12
|
||||||
|
w-full
|
||||||
|
group-data-[collapsible=icon]:h-8!
|
||||||
|
group-data-[collapsible=icon]:w-10!
|
||||||
|
group-data-[collapsible=icon]:p-2!
|
||||||
|
"
|
||||||
render={
|
render={
|
||||||
<Link
|
<Link
|
||||||
to="/"
|
to="/"
|
||||||
@ -126,12 +206,12 @@ const NavBar = () => {
|
|||||||
</SidebarMenu>
|
</SidebarMenu>
|
||||||
</SidebarHeader>
|
</SidebarHeader>
|
||||||
|
|
||||||
{/* Navigation */}
|
|
||||||
<SidebarContent>
|
<SidebarContent>
|
||||||
<SidebarGroup>
|
{/* Navigation */}
|
||||||
<SidebarGroupLabel className="text-lg">
|
<SidebarGroup className="p-2">
|
||||||
|
<GroupHeader>
|
||||||
Navigation
|
Navigation
|
||||||
</SidebarGroupLabel>
|
</GroupHeader>
|
||||||
|
|
||||||
<SidebarGroupContent>
|
<SidebarGroupContent>
|
||||||
<SidebarMenu>
|
<SidebarMenu>
|
||||||
@ -139,15 +219,18 @@ const NavBar = () => {
|
|||||||
const Icon = item.icon;
|
const Icon = item.icon;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SidebarMenuItem key={item.href}>
|
<SidebarMenuItem
|
||||||
|
key={item.href}
|
||||||
|
className={menuItemClass}
|
||||||
|
>
|
||||||
<SidebarMenuButton
|
<SidebarMenuButton
|
||||||
tooltip={item.title}
|
tooltip={item.title}
|
||||||
onClick={handleCloseMenu}
|
onClick={handleCloseMenu}
|
||||||
className="w-full"
|
className={buttonClass}
|
||||||
render={
|
render={
|
||||||
<NavLink
|
<NavLink
|
||||||
to={item.href}
|
to={item.href}
|
||||||
className="flex w-full items-center gap-2 text-base"
|
className={linkClass}
|
||||||
>
|
>
|
||||||
<Icon className="size-6 shrink-0" />
|
<Icon className="size-6 shrink-0" />
|
||||||
|
|
||||||
@ -166,22 +249,22 @@ const NavBar = () => {
|
|||||||
|
|
||||||
{/* Administration */}
|
{/* Administration */}
|
||||||
{user.is_admin && (
|
{user.is_admin && (
|
||||||
<SidebarGroup>
|
<SidebarGroup className="p-2">
|
||||||
<SidebarGroupLabel className="text-lg">
|
<GroupHeader>
|
||||||
Administration
|
Administration
|
||||||
</SidebarGroupLabel>
|
</GroupHeader>
|
||||||
|
|
||||||
<SidebarGroupContent>
|
<SidebarGroupContent>
|
||||||
<SidebarMenu>
|
<SidebarMenu>
|
||||||
<SidebarMenuItem>
|
<SidebarMenuItem className={menuItemClass}>
|
||||||
<SidebarMenuButton
|
<SidebarMenuButton
|
||||||
tooltip="Comptes existants"
|
tooltip="Comptes existants"
|
||||||
onClick={handleCloseMenu}
|
onClick={handleCloseMenu}
|
||||||
className="w-full"
|
className={buttonClass}
|
||||||
render={
|
render={
|
||||||
<NavLink
|
<NavLink
|
||||||
to="/users"
|
to="/users"
|
||||||
className="flex w-full items-center gap-2 text-base"
|
className={linkClass}
|
||||||
>
|
>
|
||||||
<Users className="size-6 shrink-0" />
|
<Users className="size-6 shrink-0" />
|
||||||
|
|
||||||
@ -201,16 +284,16 @@ const NavBar = () => {
|
|||||||
{/* Déconnexion */}
|
{/* Déconnexion */}
|
||||||
<SidebarFooter>
|
<SidebarFooter>
|
||||||
<SidebarMenu>
|
<SidebarMenu>
|
||||||
<SidebarMenuItem>
|
<SidebarMenuItem className={menuItemClass}>
|
||||||
<SidebarMenuButton
|
<SidebarMenuButton
|
||||||
tooltip="Déconnexion"
|
tooltip="Déconnexion"
|
||||||
onClick={handleCloseMenu}
|
onClick={handleCloseMenu}
|
||||||
className="w-full"
|
className={buttonClass}
|
||||||
render={
|
render={
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={logout}
|
onClick={logout}
|
||||||
className="flex w-full items-center gap-2 text-base"
|
className={linkClass}
|
||||||
>
|
>
|
||||||
<LogOut className="size-6 shrink-0" />
|
<LogOut className="size-6 shrink-0" />
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user