Ecommerce Template
Next.js·React 등으로 만든 최신 전자상거래 템플릿
Tikèm(tikem.co)은 하이티와 해외 한인 대상 티켓 플랫폼으로, 공연·파티·축제 등을 확인하고 MonCash 또는 카드로 결제 가능
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.
커머스TypeScript · JavaScriptGitHub @edlight123온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 README에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
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 }.