Application web transactionnelle de gestion de stationnement à Montréal avec système de réservation et paiement en ligne.
- Description
- Fonctionnalités
- Technologies utilisées
- Prérequis
- Installation
- Configuration
- Utilisation
- Structure du projet
- API Routes
- Base de données
- Déploiement
- Auteur
QuickParking est une plateforme moderne de gestion de places de stationnement payantes à Montréal. L'application permet aux utilisateurs de :
- Rechercher et visualiser les places de stationnement disponibles
- Réserver des places de stationnement en temps réel
- Effectuer des paiements sécurisés via Stripe
- Gérer leur profil et historique de réservations
Les administrateurs peuvent gérer l'ensemble du système (utilisateurs, parkings, réservations, paiements).
- Authentification sécurisée avec Clerk
- Visualisation des places de stationnement disponibles
- Système de réservation en temps réel
- Paiements sécurisés avec Stripe
- Historique des réservations et paiements
- Gestion du profil utilisateur
- Gestion complète des utilisateurs
- Gestion des places de stationnement
- Suivi des réservations
- Gestion des paiements
- Dashboard administrateur
- Next.js 16 - Framework React avec App Router
- TypeScript - Typage statique
- Tailwind CSS 4 - Framework CSS
- Next.js API Routes - API REST
- Prisma - ORM pour PostgreSQL
- PostgreSQL - Base de données
- Neon - Hébergement PostgreSQL serverless
- Clerk - Authentification et gestion des utilisateurs
- Stripe - Traitement des paiements
- Stripe Webhooks - Gestion des événements de paiement
- ESLint - Linting
- tsx - Exécution TypeScript
- bcrypt - Hashing de mots de passe
- Node.js (version 20 ou supérieure)
- npm ou yarn
- PostgreSQL (ou compte Neon)
- Compte Clerk
- Compte Stripe
- Cloner le repository
git clone https://github.com/CanadaBadiane/QuickParking.git
cd quickparking- Installer les dépendances
npm install- Configurer la base de données
# Générer le client Prisma
npx prisma generate
# Importer les données de parking
npx tsx scripts/importParkingSpot.tsCréer un fichier .env.local à la racine du projet avec les variables suivantes :
# Database
DATABASE_URL="postgresql://user:password@host:5432/database"
# Clerk
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=your_clerk_publishable_key
CLERK_SECRET_KEY=your_clerk_secret_key
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
# Stripe
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=your_stripe_publishable_key
STRIPE_SECRET_KEY=your_stripe_secret_key
STRIPE_WEBHOOK_SECRET=your_stripe_webhook_secretnpm run devL'application sera accessible sur http://localhost:3000
Pour tester les paiements en local, vous devez configurer le webhook Stripe :
# 1. Connectez-vous à Stripe CLI
stripe login
# 2. Lancez le webhook listener (dans un terminal séparé)
stripe listen --forward-to localhost:3000/api/stripe/webhookLe webhook secret (whsec_...) affiché doit être copié dans votre .env.local comme STRIPE_WEBHOOK_SECRET
npm run build
npm start# Linting
npm run lint
# Vider la base de données
npx prisma migrate reset
# Exécuter les migrations
npx prisma migrate devquickparking/
├── app/ # App Router Next.js
│ ├── api/ # API Routes
│ │ ├── paiements/ # Endpoints paiements
│ │ ├── parking-spots/ # Endpoints parkings
│ │ ├── reservations/ # Endpoints réservations
│ │ ├── stripe/ # Webhooks Stripe
│ │ └── users/ # Endpoints utilisateurs
│ ├── components/ # Composants réutilisables
│ ├── allPaiements/ # Page admin paiements
│ ├── allParkings/ # Page admin parkings
│ ├── allReservations/ # Page admin réservations
│ ├── allUsers/ # Page admin utilisateurs
│ ├── connexion/ # Page connexion
│ ├── inscription/ # Page inscription
│ ├── paiements/ # Page paiements
│ ├── reservation/ # Page réservation
│ ├── userProfile/ # Page profil utilisateur
│ └── ... # Autres pages
├── lib/ # Bibliothèques et utilitaires
│ ├── prisma.ts # Client Prisma
│ ├── types.ts # Types TypeScript
│ └── generated/ # Prisma généré
├── prisma/ # Configuration Prisma
│ ├── schema.prisma # Schéma de base de données
│ └── migrations/ # Migrations
├── postman/ # Collection Postman
├── scripts/ # Scripts utilitaires
└── docs/ # Documentation
POST /api/users- Créer un utilisateurGET /api/users/[id]- Obtenir un utilisateurPATCH /api/users/[id]- Mettre à jour un utilisateurDELETE /api/users/[id]- Supprimer un utilisateur (soft delete)POST /api/users/login- ConnexionGET /api/users/dashboard- Lister tous les utilisateurs (admin)
GET /api/parking-spots- Liste toutes les placesGET /api/parking-spots/[id]- Obtenir une place
GET /api/reservations- Liste toutes les réservations d'un utilisateurPOST /api/reservations- Créer une réservationGET /api/reservations/[id]- Obtenir une réservationPATCH /api/reservations/[id]- Mettre à jour une réservationGET /api/reservations/dashboard- Liste toutes les réservations (admin)
GET /api/paiements- Liste tous les paiements d'un utilisateurPOST /api/paiements- Créer un paiementGET /api/paiements/[id]- Obtenir un paiementGET /api/paiements/dashboard- Liste tous les paiements (admin)
POST /api/stripe/webhook- Webhook Stripe
model User {
userId String @id @default(cuid())
clerkId String @unique
name String
email String @unique
phone String?
role String @default("user")
password String
confirmationPassword String
createdAt DateTime @default(now())
deletedAt DateTime?
}model ParkingSpot {
parkingSpotId String @id @default(cuid())
name String
description String
lat Float
lng Float
arrondissement String
pricePerHour Float
isAvailable Boolean
canReserve Boolean
maxDuration Int @default(120)
features String[]
lastUpdated String
}model Reservation {
reservationId String @id @default(cuid())
userId String
parkingSpotId String
startDateTime DateTime @default(now())
endDateTime DateTime
extraMinutes String?
status ReservationStatus
createdAt DateTime @default(now())
updatedAt DateTime
}
enum ReservationStatus {
active
completed
cancelled
}model Paiement {
paiementId String @id @default(cuid())
clerkId String
userId String
parkingSpotId String
reservationId String?
stripePaymentIntentId String?
amount Float
duration Int
method String @default("card")
status PaiementStatus
startDateTime DateTime?
endDateTime DateTime?
createdAt DateTime @default(now())
}
enum PaiementStatus {
pending
completed
failed
}- Connecter votre repository GitHub à Vercel
- Configurer les variables d'environnement
- Déployer automatiquement
DATABASE_URLNEXT_PUBLIC_CLERK_PUBLISHABLE_KEYCLERK_SECRET_KEYNEXT_PUBLIC_STRIPE_PUBLISHABLE_KEYSTRIPE_SECRET_KEYSTRIPE_WEBHOOK_SECRET
La collection Postman est disponible dans postman/QuickParking.postman_collection.json pour tester tous les endpoints de l'API.
- Les mots de passe sont hashés avec bcrypt
- L'authentification utilise Clerk avec JWT tokens
- Les paiements sont sécurisés via Stripe
- Soft delete pour les utilisateurs (deletedAt)
- Mise à jour automatique du statut des réservations expirées
- Support des réservations avec durée maximale configurable
Canada Badiane
- GitHub: @CanadaBadiane