Ecommerce Template
Modern ecommerce template built with Next.js 16, React 19, Drizzle, Better Auth, Supabase, and Stripe.
Tikèm (tikem.co) is the ticketing platform for Haiti and the diaspora. Concerts, parties, festivals and culture: discover what is on and pay with MonCash or card.
Translation pending
CommerceTypeScript · JavaScriptGitHub @edlight123OnlineOwner 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
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗A production-quality, premium web application for discovering events and buying tickets in Haiti. Built with Next.js 14, TypeScript, Tailwind CSS, and Firebase, featuring an Eventbrite/Posh-like premium experience with advanced animations, modern UI components, and comprehensive features.
Tikèm/
├── app/ # Next.js App Router
│ ├── page.tsx # Premium home page with carousel
│ ├── loading.tsx # App-wide loading skeleton
│ ├── dashboard/ # Attendee dashboard
│ ├── discover/ # Discover page with advanced search
│ ├── events/[id]/ # Event detail pages
│ ├── favorites/ # Favorites page with empty state
│ ├── tickets/ # My tickets page
│ ├── organizer/ # Organizer features
│ │ ├── page.tsx # Organizer dashboard
│ │ ├── events/ # Event management
│ │ ├── analytics/ # Analytics with charts
│ │ └── scan/ # QR code scanner
│ ├── auth/ # Authentication pages
│ └── api/ # API routes
├── components/ # React components
│ ├── ui/ # Base UI components (10)
│ ├── charts/ # Chart components
│ ├── EventCard.tsx # Premium event card
│ ├── AdvancedSearch.tsx # Advanced search component
│ ├── EmptyState.tsx # Empty state component
│ ├── Confetti.tsx # Confetti animation
│ └── SuccessCelebration.tsx # Success modal
├── lib/ # Utilities and helpers
├── types/ # TypeScript types
├── public/ # Static assets
└── tailwind.config.ts # Premium design system
loading.tsx)Clone the repository
git clone <repository-url>
cd Tikèm
Install dependencies
npm install
Set up environment variables
cp .env.example .env.local
Fill in your credentials in .env.local (see FIREBASE_SETUP.md for detailed guide)
Set up Firebase
Follow the instructions in FIREBASE_SETUP.md:
Run development server
npm run dev
Open in browser Navigate to http://localhost:3000
See FIREBASE_SETUP.md for comprehensive Firebase setup instructions including:
Also see SETUP.md for:
Tikèm/
├── app/ # Next.js app router pages
│ ├── api/ # API routes
│ │ ├── create-checkout-session/ # Stripe checkout
│ │ └── webhooks/ # Payment webhooks
│ ├── events/ # Event browsing & details
│ ├── tickets/ # User ticket management
│ ├── favorites/ # Favorite events
│ ├── organizer/ # Organizer dashboard
│ │ ├── events/ # Event management
│ │ ├── analytics/ # Sales analytics
│ │ ├── settings/ # Payment settings
│ │ ├── scan/ # Ticket scanning
│ │ └── promo-codes/ # Discount codes
│ └── profile/ # User profile
├── components/ # Reusable React components
│ ├── ImageUpload.tsx # Image upload widget
│ └── Navbar.tsx # Navigation
├── lib/ # Utility libraries
│ ├── firebase/ # Firebase client utilities
│ ├── firebase-db/ # Firebase Firestore wrapper (Supabase-compatible API)
│ ├── email.ts # Email service (Resend)
│ ├── whatsapp.ts # WhatsApp service (Twilio)
│ ├── qrcode.ts # QR code generation
│ └── demo.ts # Demo mode utilities
├── .env.example # Environment variables template
├── FIREBASE_SETUP.md # Firebase setup guide
├── SETUP.md # Integration setup guide
└── README.md # This file
Required variables (see .env.example):
# Firebase (Required)
NEXT_PUBLIC_FIREBASE_API_KEY=
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=
NEXT_PUBLIC_FIREBASE_PROJECT_ID=
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=
NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=
NEXT_PUBLIC_FIREBASE_APP_ID=
# Firebase Admin SDK (Required for server-side)
FIREBASE_ADMIN_PROJECT_ID=
FIREBASE_ADMIN_CLIENT_EMAIL=
FIREBASE_ADMIN_PRIVATE_KEY=
# Stripe (required for payments)
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=
STRIPE_SECRET_KEY=
STRIPE_WEBHOOK_SECRET=
# Resend (required for emails)
RESEND_API_KEY=
# Twilio WhatsApp (optional)
TWILIO_ACCOUNT_SID=
TWILIO_AUTH_TOKEN=
TWILIO_WHATSAPP_NUMBER=
# MonCash (optional, for Haiti payments)
MONCASH_CLIENT_ID=
MONCASH_SECRET_KEY=
MONCASH_MODE=
Use test card numbers:
Set NEXT_PUBLIC_DEMO_MODE=true to enable demo mode with:
Push to GitHub
git push origin main
Import to Vercel
Configure Webhooks
Contributions are welcome! Please:
MIT License - see LICENSE file for details
For setup help or questions:
Built with:
The platform uses Firebase (Firestore) as its primary database with a Supabase-compatible API wrapper for easier migration and development. This means:
Tikèm - Experience Haiti's Best Events 🇭🇹
5. **Run the development server**
```bash
npm run dev
Open your browser
Navigate to http://localhost:3000
Tikèm/
├── app/ # Next.js App Router pages
│ ├── auth/ # Authentication pages
│ ├── events/ # Event pages
│ ├── tickets/ # Ticket pages
│ ├── organizer/ # Organizer dashboard
│ └── page.tsx # Home page
├── components/ # Reusable React components
├── config/ # Configuration files
├── lib/ # Utility functions
├── types/ # TypeScript type definitions
├── supabase/ # Supabase configuration
└── public/ # Static assets
Tikèm is designed with multi-tenancy in mind for future expansion to HaitiPass and HaitiEvents brands.
Built with ❤️ for Haiti 🇭🇹
Real-time and segmented notifications are supported via a progressive enhancement layer:
public/sw.js) handles push events, offline caching, and notification action clicks.POST /api/push/subscribe, POST /api/push/unsubscribe, POST /api/push/send, POST /api/push/test.reminders, promotions, updates for targeted sends.userId enabling user-specific targeting.Navigate to /settings/notifications to adjust topics and manage your subscription.
The page renders components/settings/NotificationPreferences.tsx providing:
localStorage key: eh_push_topics)Add VAPID keys to .env.local:
NEXT_PUBLIC_VAPID_PUBLIC_KEY=your_public_key
VAPID_PRIVATE_KEY=your_private_key
# Optional but recommended for managed tests
PUSH_TEST_SECRET=your_random_secret
Generate with the web-push library or existing tooling.
NEXT_PUBLIC_VAPID_PUBLIC_KEYVAPID_PRIVATE_KEYPUSH_TEST_SECRET (any long random string; enables secure remote tests)
Redeploy after saving./settings/notifications to subscribe. Use the Send Test button for an end-to-end check (it issues a POST to /api/push/test).https://<your-app>.vercel.app/api/push/test?secret=<PUSH_TEST_SECRET>.curl "https://tikem.co/api/push/test?secret=$PUSH_TEST_SECRET"
Successful responses include sent and pruned arrays. A 401 Invalid secret error means the query parameter or Vercel env is incorrect; 404 No valid subscriptions means nobody is currently subscribed on that environment./api/push/send body:{ "title": "Promo", "body": "New discount!", "topics": ["promotions"] }
Omit topics to broadcast to all.
/api/push/send-user body:{ "userId": "uid_abc123", "title": "Reminder", "body": "Event starting soon", "url": "/tickets" }
Applies per-user rate limit (default: 20 notifications/hour) and prunes expired endpoints.
/api/push/test (no body) for system validation.All send/test/user endpoints append a document to pushDispatchLogs with:
{
"kind": "topic|user|test",
"topics": ["promotions"], // topic only
"userId": "uid_abc123", // user only
"title": "Promo",
"body": "New discount!",
"url": "/tickets",
"sentCount": 3,
"successCount": 3,
"pruned": ["endpoint1"],
"timestamp": "2025-11-29T02:15:00.000Z"
}
Use this collection for future analytics (CTR, failure rates, topic adoption).
| Symptom | Likely Cause | Fix |
|---|---|---|
| Test notification returns 404 "No valid subscriptions" | Existing subscription stored without encryption keys | Disable then re-enable push (updates keys) |
| Notifications not received after enabling | Browser permission still "default" or service worker not active | Refresh page; ensure HTTPS + granted permission |
| Some endpoints pruned immediately | Stale or invalidated subscription | Re-subscribe; keys rotate automatically |
| Rate limit error (429) on user send | Exceeded 20 targeted sends/hour for user | Wait for window reset or lower volume |
If upgrading from earlier implementation (before key extraction fix), users must re-enable notifications to populate keys.p256dh and keys.auth for web-push encryption.
Endpoint: POST /api/push/send-user
Body example:
{ "userId": "uid_abc123", "title": "Ticket Update", "body": "Your ticket was transferred", "url": "/tickets" }
Behavior:
userId matches.20/hour) via pushRateLimits collection.pushDispatchLogs with counts & pruned list.Helper (client/server): sendUserNotification(userId, title?, body?, url?, data?) in lib/push.ts.
Each send (topic or user) can be extended to log to pushDispatchLogs:
{
"kind": "user", // or "topic"
"userId": "uid_abc123", // optional for topic
"title": "Ticket Update",
"sentCount": 2,
"successCount": 2,
"pruned": [],
"timestamp": "2025-11-29T03:12:45.000Z"
}
resetAt).{ error: 'Rate limit exceeded', limit: 20 }.