ec-cube
EC-CUBE is the most popular e-commerce solution in Japan
Les meilleurs tatoueurs autour de toi. Explore leurs portfolios, choisis ton style et demande ton projet en quelques secondes.
Translation pending
CommerceTypeScript · JavaScriptGitHub @tato202106OnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Site qui permet de prendre rendez-vous chez des tatoueur, envoyer des images et chatter directement avec la personne et qu'elle puisse payer directement
Translation pending
Loading the full README.
Read the full README ↗Marketplace mobile-first qui met en relation des clients et des tatoueurs.
Je veux un tatoueur → je vois ceux autour de moi → je regarde leurs tatouages → je choisis → je contacte/réserve.
Le mobile (375–430 px) est la version de référence ; le desktop en est une adaptation.
Cahier des charges : docs/SPEC.md · décisions de conception : docs/DECISIONS.md.
Prérequis : Node.js ≥ 20.9.
npm install # copie aussi le worker MapLibre dans public/vendor (postinstall)
npm run dev # http://localhost:3000
Production :
npm run build && npm run start
Il n'y a pas encore de backend utilisateur : la connexion (/connexion) ne demande qu'un prénom.
Profil → « Passer en mode tatoueur·se / client » pour changer de côté ; « Réinitialiser la démo » remet les données à zéro.
vercel.json fixe le framework (Next.js), les commandes et la région (Paris, cdg1) : le projet se
déploie même si le projet Vercel a été créé sur un dépôt vide (préréglage « Other » sinon, qui ne
publie que public/ → 404). npm install lance le postinstall (copie du worker MapLibre) puis next build.
main) — fusionner la branche de travail dans main pour mettre à jour le site principal.FileStorage avant une vraie mise en production.| Commande | Rôle |
|---|---|
npm run dev | Serveur de développement (Turbopack) |
npm run build / npm run start | Build et serveur de production |
npm run lint | ESLint (config Next + TypeScript) |
npm run typecheck | next typegen + tsc --noEmit (TypeScript strict) |
npm test | Tests unitaires Vitest (tests/unit) |
npm run test:e2e | Tests Playwright sur iPhone SE 375, iPhone 15 393, iPhone Pro Max 430, Pixel 7 412, Desktop 1280 |
npm run icons | Régénère les icônes PWA depuis le logo SVG |
node scripts/screenshots.mjs [url] --sizes=375,430 | Captures d'écran des écrans clés (FAKE_TILES=1 hors réseau) |
node scripts/bundle-size.mjs [url] | Poids du JS initial par page (gzip et brotli) |
Les tests e2e démarrent npm run start sur le port 3100 (faire npm run build avant), ou utilisent PLAYWRIGHT_BASE_URL.
CHROMIUM_PATH permet d'indiquer un Chromium déjà installé.
Voir .env.example.
| Variable | Défaut | Rôle |
|---|---|---|
NEXT_PUBLIC_MAP_STYLE_URL | (vide) | Style MapLibre (URL JSON). Vide = fond clair CARTO Positron (raster gratuit, attribution OSM/CARTO affichée) |
UPLOAD_DIR | .data/uploads | Dossier du stockage disque des images uploadées |
STRIPE_SECRET_KEY | (vide) | Clé secrète Stripe. Vide = paiement en mode démo |
STRIPE_PRICE_MONTHLY / STRIPE_PRICE_ANNUAL | (vide) | Identifiants de prix Stripe (sinon prix créés à la volée depuis lib/pro-offer.ts) |
STRIPE_WEBHOOK_SECRET | (vide) | Secret de signature du webhook Stripe (/api/billing/webhook). Vide = webhook désactivé |
ADMIN_PASSWORD | (vide) | Mot de passe de la page /admin (validation des profils tatoueurs). Vide = page désactivée |
NEXT_PUBLIC_SITE_URL | https://fastattoo.com | URL publique (sitemap, robots) |
app/ Routes (App Router)
page.tsx Accueil
explorer/ Carte + bottom sheet (cœur du produit)
tatoueurs/[slug]/ Profil tatoueur, /demande = formulaire 8 étapes
messages/ Liste et fil de discussion
favoris/ profil/ connexion/ notifications/ offline/
pro/ Espace tatoueur : dashboard, demandes, calendrier, portfolio, onboarding, abonnement
api/billing/ config, checkout, verify, subscription, upgrade (Stripe)
mon-abonnement/ Abonnement du tatoueur (slides pour passer à l'annuel)
devenir-tatoueur/paiement/ Paiement obligatoire (fin d'inscription ; accès bloqué sinon, voir proxy.ts)
proxy.ts Renvoie un tatoueur connecté sans abonnement actif vers le paiement
api/artists/ search, suggest, cards, [slug]
api/uploads/ Upload d'images (normalisation sharp)
media/ Variantes d'images (art de démo, avatars, uploads)
manifest.ts Manifest PWA
components/
ui/ Primitives (Button, Sheet, Picture, Icon, Chip…)
layout/ Navigation basse / desktop, runtime (toasts, SW)
explore/ Carte MapLibre, bottom sheet, carrousel, filtres, recherche
artist/ Cards, portfolio masonry, plein écran, avis, mini-carte
request/ chat/ client/ pro/ account/ pwa/ home/
lib/ Logique métier pure et testable
data/ Interface ArtistRepository + implémentation mémoire + données de démo
search/ parse.ts (recherche intelligente), engine.ts, filtres ↔ URL
storage/ Interface FileStorage + stockage disque local
billing/ Forfaits (plans.ts, testé) + client Stripe (stripe.ts)
notifications/ Canaux de notification (in-app, push navigateur)
store/ État client (Zustand) des Phases 3–5 + données de démo
art/ Générateur procédural des visuels de démo
images.ts geo.ts calendar.ts dates.ts masonry.ts
public/sw.js Service worker
tests/unit, tests/e2e Vitest, Playwright
| Élément | Statut |
|---|---|
| Recherche, filtres, géolocalisation, carte, pagination | Réel (API + moteur testé), sur données de démo |
| Tatoueurs, portfolios, avis, créneaux publics | Démo : 30 tatoueurs générés (8 villes), visuels de tatouage générés procéduralement (pas de vraies photos) |
| Pipeline d'images (5 tailles, AVIF/WebP, cache immuable) | Réel, y compris pour les photos uploadées |
| Upload de photos (portfolio, inspirations, messages) | Réel, stockage disque local ; non authentifié |
| Connexion / inscription | Simulée : pas de mot de passe, session sur l'appareil |
| Demandes, messagerie, rendez-vous, calendrier, favoris, avis laissés, notifications | Simulés côté client (localStorage) : un seul appareil, pas de temps réel entre deux utilisateurs |
| Statistiques tatoueur | « Vues du profil » = valeur de démo ; demandes et taux de réponse calculés |
| Notifications push | Architecture prête (canaux + push dans le SW) ; pas d'envoi serveur |
| Abonnement tatoueur (179 €/an « 1 mois offert » ou 19 €/mois, paiement immédiat, sans essai) | Réel via Stripe Checkout à l'inscription (/devenir-tatoueur/inscription) si STRIPE_SECRET_KEY est défini, enregistré dans Neon ; slides + passage à l'annuel sur /mon-abonnement. L'espace pro /pro reste une démo (aucun encaissement) |
| Mise en avant, commission (reste de la Phase 6) | Non implémentés — point d'extension Artist.promoted |
npm run lint, npm run typecheck, npm test (33 tests) : OK.npm run test:e2e : 89 tests OK sur les 5 viewports (1 test mobile ignoré sur desktop).docs/DECISIONS.md § Performance pour les chiffres et les limites connues.