From cc4412d151891c8e13966db7e23f79d61ae977d7 Mon Sep 17 00:00:00 2001 From: gpatruno Date: Wed, 8 Jul 2026 13:28:51 +0200 Subject: [PATCH] =?UTF-8?q?update=20esth=C3=A9tique?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 8 +- docker-compose.server.yml | 2 + docker-compose.yml | 2 + .../migration.sql | 24 ++ prisma/schema.prisma | 25 ++ src/app/page.tsx | 5 + src/components/site/ReviewCard.tsx | 55 ++++ src/components/site/ReviewStars.tsx | 33 +++ src/components/site/ReviewsCarousel.tsx | 167 +++++++++++ src/components/site/ReviewsSection.tsx | 62 +++++ src/components/site/SiteHeader.tsx | 6 + src/components/site/WeekScheduleCalendar.tsx | 20 +- src/lib/constants.ts | 2 + src/lib/google-reviews.ts | 259 ++++++++++++++++++ 14 files changed, 663 insertions(+), 7 deletions(-) create mode 100644 prisma/migrations/20260615210000_google_reviews/migration.sql create mode 100644 src/components/site/ReviewCard.tsx create mode 100644 src/components/site/ReviewStars.tsx create mode 100644 src/components/site/ReviewsCarousel.tsx create mode 100644 src/components/site/ReviewsSection.tsx create mode 100644 src/lib/google-reviews.ts diff --git a/README.md b/README.md index 59d617c..043ee98 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Site vitrine et back-office pour **Gaufrement Bon** (gaufres artisanales à Bagn ## Fonctionnalités -- **Site public** : hero, menu par catégories (sucrées, salées, du mois), galerie, horaires et contact. +- **Site public** : hero, menu par catégories (sucrées, salées, du mois), galerie, avis Google (synchronisés en base), horaires et contact. - **Administration** (`/admin`) : connexion par session, gestion du menu, de la galerie et des textes / images du site. - **Upload d’images** : redimensionnement via Sharp, stockage dans `public/uploads/`. - **Base SQLite** : Prisma 7, migrations versionnées, seed au premier démarrage Docker. @@ -40,6 +40,8 @@ Sans fichier `.env`, les valeurs par défaut suivantes s’appliquent : | `AUTH_SECRET` | secret de dev (à changer en prod) | | `ADMIN_EMAIL` | `admin@lagaufredor.local` | | `ADMIN_PASSWORD` | `changeme123` | +| `GOOGLE_PLACES_API_KEY` | *(aucun — section avis masquée)* | +| `GOOGLE_PLACE_ID` | ID par défaut dans `src/lib/constants.ts` | Exemple `.env` : @@ -48,6 +50,9 @@ DATABASE_URL="file:./dev.db" AUTH_SECRET="remplacer-par-une-longue-chaine-aleatoire" ADMIN_EMAIL="admin@example.com" ADMIN_PASSWORD="mot-de-passe-fort" +# Optionnel — avis Google Maps (Places API New) +# GOOGLE_PLACES_API_KEY= +# GOOGLE_PLACE_ID=ChIJN_OqSb2ltRIRhA21X2loXQI # Optionnel — rate limiting distribué # UPSTASH_REDIS_REST_URL= # UPSTASH_REDIS_REST_TOKEN= @@ -123,6 +128,7 @@ docker/ # Entrypoint conteneur - Changer `ADMIN_EMAIL` et `ADMIN_PASSWORD` avant le premier seed, ou créer l’admin puis modifier le mot de passe. - Servir le site derrière HTTPS (Nginx ou équivalent). - Configurer Upstash si plusieurs instances partagent le rate limiting. +- Pour afficher les avis Google sous la galerie : activer la [Places API (New)](https://developers.google.com/maps/documentation/places/web-service/overview) sur un projet Google Cloud, créer une clé API, et définir `GOOGLE_PLACES_API_KEY`. L’ID de lieu (`GOOGLE_PLACE_ID`) est préconfiguré pour Gaufrement Bon ; vérifiez-le avec l’[outil Place ID](https://developers.google.com/maps/documentation/javascript/place-id) si besoin. ## Licence diff --git a/docker-compose.server.yml b/docker-compose.server.yml index 6900916..6efb17e 100644 --- a/docker-compose.server.yml +++ b/docker-compose.server.yml @@ -21,6 +21,8 @@ services: NODE_ENV: production UPSTASH_REDIS_REST_URL: ${UPSTASH_REDIS_REST_URL:-} UPSTASH_REDIS_REST_TOKEN: ${UPSTASH_REDIS_REST_TOKEN:-} + GOOGLE_PLACES_API_KEY: ${GOOGLE_PLACES_API_KEY:-} + GOOGLE_PLACE_ID: ${GOOGLE_PLACE_ID:-} volumes: - gauffre-data:/app/data - gauffre-uploads:/app/public/uploads diff --git a/docker-compose.yml b/docker-compose.yml index 4dcf1a9..b73b309 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -12,6 +12,8 @@ services: # Optionnel : rate limiting distribué (sinon fallback mémoire) UPSTASH_REDIS_REST_URL: ${UPSTASH_REDIS_REST_URL:-} UPSTASH_REDIS_REST_TOKEN: ${UPSTASH_REDIS_REST_TOKEN:-} + GOOGLE_PLACES_API_KEY: ${GOOGLE_PLACES_API_KEY:-} + GOOGLE_PLACE_ID: ${GOOGLE_PLACE_ID:-} volumes: - gauffre-data:/app/data - gauffre-uploads:/app/public/uploads diff --git a/prisma/migrations/20260615210000_google_reviews/migration.sql b/prisma/migrations/20260615210000_google_reviews/migration.sql new file mode 100644 index 0000000..7412372 --- /dev/null +++ b/prisma/migrations/20260615210000_google_reviews/migration.sql @@ -0,0 +1,24 @@ +-- CreateTable +CREATE TABLE "GoogleReviewsMeta" ( + "id" TEXT NOT NULL PRIMARY KEY DEFAULT 'default', + "placeId" TEXT NOT NULL, + "rating" REAL, + "reviewCount" INTEGER, + "googleMapsUri" TEXT NOT NULL, + "syncedAt" DATETIME NOT NULL +); + +-- CreateTable +CREATE TABLE "GoogleReview" ( + "id" TEXT NOT NULL PRIMARY KEY, + "authorName" TEXT NOT NULL, + "authorUri" TEXT, + "authorPhotoUri" TEXT, + "rating" REAL NOT NULL, + "text" TEXT NOT NULL, + "relativeTime" TEXT NOT NULL DEFAULT '', + "googleMapsUri" TEXT, + "sortOrder" INTEGER NOT NULL DEFAULT 0, + "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" DATETIME NOT NULL +); diff --git a/prisma/schema.prisma b/prisma/schema.prisma index c56db88..9319412 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -103,3 +103,28 @@ model TruckEventRecurrence { @@index([dayOfWeek]) } + +/** Métadonnées des avis Google (note globale, lien Maps). Une seule ligne (id = default). */ +model GoogleReviewsMeta { + id String @id @default("default") + placeId String + rating Float? + reviewCount Int? + googleMapsUri String + syncedAt DateTime @updatedAt +} + +/** Avis Google Maps synchronisés depuis l’API Places. */ +model GoogleReview { + id String @id + authorName String + authorUri String? + authorPhotoUri String? + rating Float + text String + relativeTime String @default("") + googleMapsUri String? + sortOrder Int @default(0) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} diff --git a/src/app/page.tsx b/src/app/page.tsx index 3f270df..27e41f6 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,5 +1,6 @@ import { Footer } from "@/components/site/Footer"; import { GallerySection } from "@/components/site/GallerySection"; +import { ReviewsSection } from "@/components/site/ReviewsSection"; import { ScheduleSection } from "@/components/site/ScheduleSection"; import { Hero } from "@/components/site/Hero"; import { HeroIntro } from "@/components/site/HeroIntro"; @@ -7,6 +8,7 @@ import { MenuSection } from "@/components/site/MenuSection"; import { SiteHeader } from "@/components/site/SiteHeader"; import { prisma } from "@/lib/prisma"; import { getCustomWaffleConfig } from "@/lib/custom-waffle-content"; +import { getGoogleReviews } from "@/lib/google-reviews"; import { getPublicSiteContent } from "@/lib/site-content"; import { getPublicTruckEvents } from "@/lib/truck-event"; import { getPublicTruckRecurrences } from "@/lib/truck-recurrence"; @@ -24,6 +26,7 @@ export default async function Home() { customWaffle, truckEvents, truckRecurrences, + googleReviews, ] = await Promise.all([ prisma.waffle.findMany({ include: waffleIngredientInclude }), prisma.ingredient.findMany({ @@ -37,6 +40,7 @@ export default async function Home() { getCustomWaffleConfig(), getPublicTruckEvents(), getPublicTruckRecurrences(), + getGoogleReviews(), ]); return ( @@ -69,6 +73,7 @@ export default async function Home() { intro={site.scheduleIntro} /> + {googleReviews ? : null}