mirror of
https://github.com/BreizhHardware/Site-comptage-heure.git
synced 2026-01-18 16:17:28 +01:00
fix: update import paths for components and utilities to relative paths
This commit is contained in:
44
.dockerignore
Normal file
44
.dockerignore
Normal file
@@ -0,0 +1,44 @@
|
||||
node_modules
|
||||
.next
|
||||
.env*
|
||||
.git
|
||||
.gitignore
|
||||
README.md
|
||||
.dockerignore
|
||||
*.log
|
||||
.DS_Store
|
||||
.vscode
|
||||
.idea
|
||||
coverage
|
||||
.nyc_output
|
||||
.cache
|
||||
dist
|
||||
build
|
||||
*.tgz
|
||||
*.tar.gz
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
.npm
|
||||
.yarn-integrity
|
||||
.pnpm-debug.log*
|
||||
.npmrc
|
||||
.yarnrc
|
||||
.pnpmrc
|
||||
.prettierrc
|
||||
.eslintrc
|
||||
.eslintignore
|
||||
.prettierignore
|
||||
.stylelintrc
|
||||
postcss.config.js
|
||||
tailwind.config.js
|
||||
next.config.js
|
||||
next-env.d.ts
|
||||
tsconfig.json
|
||||
prisma/dev.db
|
||||
INITIAL_SETUP.md
|
||||
API_DOCS.md
|
||||
INDICATIONS_POUR_LLMS.md
|
||||
|
||||
21
.github/dependabot.yml
vendored
Normal file
21
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
# To get started with Dependabot version updates, you'll need to specify which
|
||||
# package ecosystems to update and where the package manifests are located.
|
||||
# Please see the documentation for all configuration options:
|
||||
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions" # See documentation for possible values
|
||||
directory: "/.github/workflow" # Location of package manifests
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/" # Location of package manifests
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
|
||||
- package-ecosystem: "docker"
|
||||
directory: "/" # Location of Dockerfile
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
43
.github/workflows/docker-build.yml
vendored
Normal file
43
.github/workflows/docker-build.yml
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
name: Build and Push Docker Image
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
build-and-push:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Prepare Docker tags
|
||||
id: prep
|
||||
run: |
|
||||
OWNER=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]')
|
||||
echo "owner=$OWNER" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
tags: |
|
||||
ghcr.io/${{ steps.prep.outputs.owner }}/site-comptage-heure:latest
|
||||
ghcr.io/${{ steps.prep.outputs.owner }}/site-comptage-heure:${{ github.sha }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -44,13 +44,10 @@ next-env.d.ts
|
||||
.idea/*
|
||||
.idea
|
||||
|
||||
INDICATIONS_POUR_LLMS.md
|
||||
public/uploads
|
||||
public/uploads/*
|
||||
prisma/dev.db
|
||||
|
||||
pnpm-lock.yaml
|
||||
.vscode/
|
||||
.vscode/*
|
||||
.vscode
|
||||
|
||||
.vscode
|
||||
11
Dockerfile
11
Dockerfile
@@ -1,10 +1,13 @@
|
||||
FROM node:22-alpine
|
||||
WORKDIR /app
|
||||
COPY package*.json ./
|
||||
RUN npm install
|
||||
COPY pnpm-lock.yaml ./
|
||||
RUN npm install -g pnpm
|
||||
RUN pnpm install --frozen-lockfile
|
||||
COPY . .
|
||||
ENV NEXTAUTH_SECRET=your_super_secret_key_here_change_in_production
|
||||
RUN npx prisma generate
|
||||
RUN npm run build
|
||||
RUN npx prisma db push
|
||||
RUN pnpm run build
|
||||
EXPOSE 3000
|
||||
CMD ["npm", "start"]
|
||||
|
||||
CMD ["pnpm", "start"]
|
||||
|
||||
80
INDICATIONS_POUR_LLMS.md
Normal file
80
INDICATIONS_POUR_LLMS.md
Normal file
@@ -0,0 +1,80 @@
|
||||
# Indications pour les LLMs - Projet Site de Comptage d'Heures
|
||||
|
||||
## Vue d'ensemble du projet
|
||||
|
||||
Ce projet est une application web Next.js pour le suivi des heures travaillées dans un club ou une organisation. Elle permet aux utilisateurs de saisir leurs heures, aux administrateurs de valider ou rejeter les demandes, et de gérer les utilisateurs et les paramètres du club.
|
||||
|
||||
## Technologies utilisées
|
||||
|
||||
- **Framework**: Next.js 15 avec App Router
|
||||
- **Base de données**: SQLite avec Prisma ORM
|
||||
- **Authentification**: NextAuth.js
|
||||
- **UI**: Radix UI avec Tailwind CSS
|
||||
- **Langage**: TypeScript
|
||||
- **Gestionnaire de paquets**: pnpm
|
||||
- **Déploiement**: Docker (optionnel)
|
||||
|
||||
## Structure du projet
|
||||
|
||||
- `app/`: Pages et API routes Next.js
|
||||
- `components/`: Composants réutilisables
|
||||
- `lib/`: Utilitaires, configuration Prisma et auth
|
||||
- `prisma/`: Schéma de base de données et migrations
|
||||
- `public/`: Assets statiques
|
||||
- `types/`: Types TypeScript personnalisés
|
||||
|
||||
## Modèles de données
|
||||
|
||||
- **User**: Utilisateurs avec email, mot de passe, rôle, prénom, nom
|
||||
- **Hour**: Entrées d'heures avec date, durée, raison, statut
|
||||
- **ClubSettings**: Paramètres du club (nom, logo)
|
||||
|
||||
## Rôles utilisateurs
|
||||
|
||||
- **MEMBER**: Peut saisir et voir ses propres heures
|
||||
- **ADMIN**: Peut valider/rejeter les heures de tous, gérer les paramètres
|
||||
- **SUPER_ADMIN**: Peut créer des comptes admin/membre, supprimer des utilisateurs
|
||||
|
||||
## Commandes importantes
|
||||
|
||||
- `pnpm dev`: Lancer le serveur de développement
|
||||
- `pnpm build`: Construire pour la production
|
||||
- `pnpm start`: Lancer en production
|
||||
- `npx prisma db push`: Appliquer les changements de schéma à la DB
|
||||
- `npx prisma generate`: Régénérer le client Prisma
|
||||
- `npx prisma studio`: Interface graphique pour la DB
|
||||
|
||||
## Points d'attention pour les LLMs
|
||||
|
||||
- Utiliser pnpm pour toutes les commandes npm
|
||||
- Le projet utilise SQLite, donc pas de migrations Prisma traditionnelles ; utiliser `db push`
|
||||
- Les heures sont stockées en minutes (entier)
|
||||
- L'authentification utilise NextAuth avec des sessions
|
||||
- Les fichiers uploadés vont dans `public/uploads/`
|
||||
- Le premier compte créé est SUPER_ADMIN
|
||||
- Vérifier les erreurs Prisma après changements de schéma
|
||||
|
||||
## API Routes
|
||||
|
||||
- `/api/auth/[...nextauth]`: Authentification
|
||||
- `/api/hours`: CRUD des heures
|
||||
- `/api/settings`: Gestion des paramètres club
|
||||
- `/api/upload`: Upload de fichiers
|
||||
- `/api/export`: Export CSV/Excel
|
||||
- `/api/users/[id]`: Gestion utilisateurs
|
||||
|
||||
## Composants UI
|
||||
|
||||
Utilise shadcn/ui basé sur Radix UI pour une cohérence.
|
||||
|
||||
## Sécurité
|
||||
|
||||
- Mots de passe hashés avec bcrypt
|
||||
- Sessions sécurisées
|
||||
- Rôles et permissions strictes
|
||||
|
||||
## Développement
|
||||
|
||||
- Utiliser TypeScript strictement
|
||||
- Respecter les conventions de nommage
|
||||
- Tester les changements dans le navigateur et via les API
|
||||
18
README.md
18
README.md
@@ -33,17 +33,20 @@ Une application web moderne pour la gestion des heures travaillées dans un club
|
||||
## Installation
|
||||
|
||||
1. **Cloner le repository**
|
||||
|
||||
```bash
|
||||
git clone https://github.com/breizhhardware/site-comptage-heure.git
|
||||
cd site-comptage-heure
|
||||
```
|
||||
|
||||
2. **Installer les dépendances**
|
||||
|
||||
```bash
|
||||
pnpm install
|
||||
```
|
||||
|
||||
3. **Configuration de la base de données**
|
||||
|
||||
```bash
|
||||
# Appliquer le schéma Prisma
|
||||
npx prisma db push
|
||||
@@ -53,8 +56,9 @@ Une application web moderne pour la gestion des heures travaillées dans un club
|
||||
```
|
||||
|
||||
4. **Variables d'environnement**
|
||||
|
||||
|
||||
Créer un fichier `.env.local` à la racine :
|
||||
|
||||
```env
|
||||
NEXTAUTH_SECRET=votre-secret-très-long-et-sécurisé
|
||||
NEXTAUTH_URL=http://localhost:3000
|
||||
@@ -68,6 +72,7 @@ Une application web moderne pour la gestion des heures travaillées dans un club
|
||||
## Utilisation
|
||||
|
||||
### Démarrage en développement
|
||||
|
||||
```bash
|
||||
pnpm dev
|
||||
```
|
||||
@@ -75,6 +80,7 @@ pnpm dev
|
||||
Ouvrir [http://localhost:3000](http://localhost:3000)
|
||||
|
||||
### Première connexion
|
||||
|
||||
- Utilisez les identifiants du Super Administrateur créé
|
||||
- Configurez le nom et le logo du club dans l'admin
|
||||
- Créez des comptes pour les administrateurs et membres
|
||||
@@ -126,6 +132,7 @@ Ouvrir [http://localhost:3000](http://localhost:3000)
|
||||
### Avec Docker
|
||||
|
||||
1. Build l'image :
|
||||
|
||||
```bash
|
||||
docker build -t comptage-heures .
|
||||
```
|
||||
@@ -134,6 +141,15 @@ Ouvrir [http://localhost:3000](http://localhost:3000)
|
||||
```bash
|
||||
docker run -p 3000:3000 comptage-heures
|
||||
```
|
||||
|
||||
3. Créer un Super Administrateur à l'intérieur du container :
|
||||
```bash
|
||||
docker exec -it <container_id> sh
|
||||
```
|
||||
Puis exécuter (pensez à modifier le nom d'utilisateur et le mot de passe si nécessaire) :
|
||||
```bash
|
||||
node scripts/create-super-admin.js
|
||||
```
|
||||
|
||||
## Contribution
|
||||
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
import { useSession } from 'next-auth/react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Label } from '@/components/ui/label';
|
||||
import { Button } from '../../components/ui/button';
|
||||
import { Input } from '../../components/ui/input';
|
||||
import { Label } from '../../components/ui/label';
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
@@ -13,8 +13,8 @@ import {
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from '@/components/ui/table';
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
} from '../../components/ui/table';
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '../../components/ui/card';
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
@@ -22,9 +22,9 @@ import {
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from '@/components/ui/dialog';
|
||||
} from '../../components/ui/dialog';
|
||||
import { toast } from 'sonner';
|
||||
import { DatePicker } from '@/components/ui/date-picker';
|
||||
import { DatePicker } from '../../components/ui/date-picker';
|
||||
import { format } from 'date-fns';
|
||||
|
||||
interface Hour {
|
||||
@@ -94,7 +94,7 @@ export default function AdminPage() {
|
||||
}
|
||||
};
|
||||
|
||||
const handleValidate = async (id: number, status: string) => {
|
||||
const handleValidate = async (id: string, status: string) => {
|
||||
await fetch(`/api/hours/${id}`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
@@ -179,7 +179,7 @@ export default function AdminPage() {
|
||||
}
|
||||
};
|
||||
|
||||
const handleDelete = async (id: number) => {
|
||||
const handleDelete = async (id: string) => {
|
||||
await fetch(`/api/hours/${id}`, {
|
||||
method: 'DELETE',
|
||||
});
|
||||
@@ -330,14 +330,14 @@ export default function AdminPage() {
|
||||
<Button
|
||||
onClick={() => handleValidate(hour.id, 'VALIDATED')}
|
||||
className="mr-2"
|
||||
disabled={hour.userId === session.user.id}
|
||||
disabled={hour.userId === session?.user?.id}
|
||||
>
|
||||
Valider
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => handleDelete(hour.id)}
|
||||
variant="destructive"
|
||||
disabled={hour.userId === session.user.id}
|
||||
disabled={hour.userId === session?.user?.id}
|
||||
>
|
||||
Supprimer
|
||||
</Button>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import NextAuth from 'next-auth';
|
||||
import { authOptions } from '@/lib/auth';
|
||||
import { authOptions } from '../../../../lib/auth'
|
||||
|
||||
const handler = NextAuth(authOptions);
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { getServerSession } from 'next-auth';
|
||||
import { authOptions } from '@/lib/auth';
|
||||
import { prisma } from '@/lib/prisma';
|
||||
import { authOptions } from '../../../../lib/auth';
|
||||
import { prisma } from '../../../../lib/prisma';
|
||||
import bcrypt from 'bcryptjs';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { getServerSession } from 'next-auth';
|
||||
import { authOptions } from '@/lib/auth';
|
||||
import { prisma } from '@/lib/prisma';
|
||||
import { authOptions } from '../../../lib/auth';
|
||||
import { prisma } from '../../../lib/prisma';
|
||||
import * as csvWriter from 'csv-writer';
|
||||
import ExcelJS from 'exceljs';
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { getServerSession } from 'next-auth';
|
||||
import { authOptions } from '@/lib/auth';
|
||||
import { prisma } from '@/lib/prisma';
|
||||
import { authOptions } from '../../../../lib/auth';
|
||||
import { prisma } from '../../../../lib/prisma';
|
||||
|
||||
export async function PUT(
|
||||
request: NextRequest,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { getServerSession } from 'next-auth';
|
||||
import { authOptions } from '@/lib/auth';
|
||||
import { prisma } from '@/lib/prisma';
|
||||
import { authOptions } from '../../../lib/auth';
|
||||
import { prisma } from '../../../lib/prisma';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
export async function GET() {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { getServerSession } from 'next-auth';
|
||||
import { authOptions } from '@/lib/auth';
|
||||
import { prisma } from '@/lib/prisma';
|
||||
import { authOptions } from '../../../lib/auth';
|
||||
import { prisma } from '../../../lib/prisma';
|
||||
|
||||
export async function GET() {
|
||||
const settings = await prisma.clubSettings.findFirst();
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { getServerSession } from 'next-auth';
|
||||
import { authOptions } from '@/lib/auth';
|
||||
import { prisma } from '@/lib/prisma';
|
||||
import { authOptions } from '../../../../lib/auth';
|
||||
import { prisma } from '../../../../lib/prisma';
|
||||
|
||||
export async function DELETE(
|
||||
request: NextRequest,
|
||||
{ params }: { params: { id: string } },
|
||||
{ params }: { params: Promise<{ id: string }> },
|
||||
) {
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session || session.user.role !== 'SUPER_ADMIN') {
|
||||
return NextResponse.json({ error: 'Accès refusé' }, { status: 403 });
|
||||
}
|
||||
|
||||
const userId = params.id;
|
||||
const { id } = await params;
|
||||
|
||||
const user = await prisma.user.findUnique({
|
||||
where: { id: userId },
|
||||
where: { id },
|
||||
include: { hours: true },
|
||||
});
|
||||
|
||||
@@ -34,7 +34,7 @@ export async function DELETE(
|
||||
}
|
||||
|
||||
await prisma.user.delete({
|
||||
where: { id: userId },
|
||||
where: { id },
|
||||
});
|
||||
|
||||
return NextResponse.json({ message: 'Utilisateur supprimé' });
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
import { useSession } from 'next-auth/react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Label } from '@/components/ui/label';
|
||||
import { Button } from '../../components/ui/button';
|
||||
import { Input } from '../../components/ui/input';
|
||||
import { Label } from '../../components/ui/label';
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
@@ -13,8 +13,8 @@ import {
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from '@/components/ui/table';
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
} from '../../components/ui/table';
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '../../components/ui/card';
|
||||
|
||||
interface Hour {
|
||||
id: number;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import type { Metadata } from 'next';
|
||||
import { Geist, Geist_Mono } from 'next/font/google';
|
||||
import './globals.css';
|
||||
import { Providers } from '@/components/providers';
|
||||
import Header from '@/components/Header';
|
||||
import { Toaster } from '@/components/ui/sonner';
|
||||
import { Providers } from '../components/providers';
|
||||
import Header from '../components/Header';
|
||||
import { Toaster } from '../components/ui/sonner';
|
||||
|
||||
const geistSans = Geist({
|
||||
variable: '--font-geist-sans',
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { signIn } from 'next-auth/react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Label } from '@/components/ui/label';
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import { Button } from '../../components/ui/button';
|
||||
import { Input } from '../../components/ui/input';
|
||||
import { Label } from '../../components/ui/label';
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '../../components/ui/card';
|
||||
|
||||
export default function LoginPage() {
|
||||
const [email, setEmail] = useState('');
|
||||
|
||||
@@ -2,7 +2,7 @@ import * as React from 'react';
|
||||
import { Slot } from '@radix-ui/react-slot';
|
||||
import { cva, type VariantProps } from 'class-variance-authority';
|
||||
|
||||
import { cn } from '@/lib/utils';
|
||||
import { cn } from '../../lib/utils';
|
||||
|
||||
const buttonVariants = cva(
|
||||
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all cursor-pointer disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
|
||||
|
||||
@@ -8,8 +8,8 @@ import {
|
||||
} from 'lucide-react';
|
||||
import { DayButton, DayPicker, getDefaultClassNames } from 'react-day-picker';
|
||||
|
||||
import { cn } from '@/lib/utils';
|
||||
import { Button, buttonVariants } from '@/components/ui/button';
|
||||
import { cn } from '../../lib/utils';
|
||||
import { Button, buttonVariants } from './button';
|
||||
|
||||
function Calendar({
|
||||
className,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import { cn } from '@/lib/utils';
|
||||
import { cn } from '../../lib/utils';
|
||||
|
||||
function Card({ className, ...props }: React.ComponentProps<'div'>) {
|
||||
return (
|
||||
|
||||
@@ -4,14 +4,14 @@ import * as React from 'react';
|
||||
import { format } from 'date-fns';
|
||||
import { Calendar as CalendarIcon } from 'lucide-react';
|
||||
|
||||
import { cn } from '@/lib/utils';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Calendar } from '@/components/ui/calendar';
|
||||
import { cn } from '../../lib/utils';
|
||||
import { Button } from './button';
|
||||
import { Calendar } from './calendar';
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
} from '@/components/ui/popover';
|
||||
} from './popover';
|
||||
|
||||
interface DatePickerProps {
|
||||
date: Date | undefined;
|
||||
|
||||
@@ -4,7 +4,7 @@ import * as React from 'react';
|
||||
import * as DialogPrimitive from '@radix-ui/react-dialog';
|
||||
import { XIcon } from 'lucide-react';
|
||||
|
||||
import { cn } from '@/lib/utils';
|
||||
import { cn } from '../../lib/utils';
|
||||
|
||||
function Dialog({
|
||||
...props
|
||||
|
||||
@@ -13,8 +13,8 @@ import {
|
||||
type FieldValues,
|
||||
} from 'react-hook-form';
|
||||
|
||||
import { cn } from '@/lib/utils';
|
||||
import { Label } from '@/components/ui/label';
|
||||
import { cn } from '../../lib/utils';
|
||||
import { Label } from './label';
|
||||
|
||||
const Form = FormProvider;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import { cn } from '@/lib/utils';
|
||||
import { cn } from '../../lib/utils';
|
||||
|
||||
function Input({ className, type, ...props }: React.ComponentProps<'input'>) {
|
||||
return (
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import * as React from 'react';
|
||||
import * as LabelPrimitive from '@radix-ui/react-label';
|
||||
|
||||
import { cn } from '@/lib/utils';
|
||||
import { cn } from '../../lib/utils';
|
||||
|
||||
function Label({
|
||||
className,
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import * as React from 'react';
|
||||
import * as PopoverPrimitive from '@radix-ui/react-popover';
|
||||
|
||||
import { cn } from '@/lib/utils';
|
||||
import { cn } from '../../lib/utils';
|
||||
|
||||
function Popover({
|
||||
...props
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import * as React from 'react';
|
||||
|
||||
import { cn } from '@/lib/utils';
|
||||
import { cn } from '../../lib/utils';
|
||||
|
||||
function Table({ className, ...props }: React.ComponentProps<'table'>) {
|
||||
return (
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
version: '3.8'
|
||||
services:
|
||||
app:
|
||||
build: .
|
||||
ports:
|
||||
- '3000:3000'
|
||||
volumes:
|
||||
- ./data:/app/prisma/data # Pour la DB SQLite
|
||||
- ./data:/app/prisma/data
|
||||
environment:
|
||||
- NEXTAUTH_SECRET=your_secret_key
|
||||
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
import type { NextConfig } from 'next';
|
||||
import path from 'path';
|
||||
|
||||
const nextConfig: NextConfig = {
|
||||
/* config options here */
|
||||
webpack: (config) => {
|
||||
config.resolve.alias['@'] = path.resolve(__dirname);
|
||||
return config;
|
||||
},
|
||||
};
|
||||
|
||||
export default nextConfig;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
{
|
||||
"name": "my-app",
|
||||
"version": "0.1.0",
|
||||
"name": "site-comptage-heure",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev --turbopack",
|
||||
"build": "next build --turbopack",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"format": "prettier --write ."
|
||||
},
|
||||
|
||||
2769
pnpm-lock.yaml
generated
Normal file
2769
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,6 @@
|
||||
const { PrismaClient } = require('@prisma/client');
|
||||
const bcrypt = require('bcryptjs');
|
||||
const { v4: uuidv4 } = require('uuid');
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
@@ -12,6 +13,7 @@ async function main() {
|
||||
email: 'test@test.fr',
|
||||
password: hashedPassword,
|
||||
role: 'SUPER_ADMIN',
|
||||
id: uuidv4(), // Ajout d'un identifiant unique
|
||||
},
|
||||
});
|
||||
console.log('Super admin created');
|
||||
|
||||
Reference in New Issue
Block a user