ai-startup-skills
创业公司做 AI 产品的 7 步 Agent Skill 合集:验证 → BP → 政策 → 路演 → 获客 → 定价 → 注册。
Translation pending
favpoll administration
Translation pending
OtherTypeScript · HTMLGitHub @JoeMof80OnlineOwner 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
Loading the full README. The saved excerpt is shown below.
⚠ This README is outdated. The schema, file structure, and component names below reflect the early project state before the ubiquitous-language rename. For the current schema, routes, environment variables, and component tree see references/PROJECT.md (the canonical reference).Read the full README ↗⚠ This README is outdated. The schema, file structure, and component names below reflect the early project state before the ubiquitous-language rename. For the current schema, routes, environment variables, and component tree see
references/PROJECT.md(the canonical reference).
A charitable polling platform where guests share their favourite things while pledging donations to charity. Organisers create favpolls for special occasions — memorials, birthdays, retirements, weddings — each with a customised poll question. Guests pledge money and split it across their favourite answers, building a permanent record of what people love most while raising funds for good causes.
| Layer | Technology |
|---|---|
| Framework | Next.js 16 (App Router, Turbopack) |
| Language | TypeScript 5 |
| Styling | Tailwind CSS v4, shadcn/ui |
| Auth | Clerk |
| Database | Supabase (PostgreSQL) |
| Payments | Stripe |
| Resend | |
| Package manager | pnpm |
app/
api/
stripe/payment-intent/ POST — creates Stripe PaymentIntent
webhooks/clerk/ POST — syncs Clerk users to Supabase
events/
new/ Create event (canvas form)
[id]/ View event (public or private)
[id]/edit/ Edit event (organiser only)
[id]/manage/ Organiser dashboard
pledges/
withdraw/ Guest pledge withdrawal (token-based)
rankings/ All-time global favourites
topics/[id]/ Per-topic leaderboard with dual ranking toggle
sign-in/, sign-up/ Clerk auth pages
components/
canvas/ Sub-components used only by event-canvas
canvas-sidebar.tsx Charity, date, privacy, shared fund settings
poll-editor.tsx Topic picker and poll framing editor
share-screen.tsx Post-publish share link screen
topic-picker.tsx Browse and select topics by category
event-canvas/ Full create/edit form
index.tsx JSX — occasion tabs, hero, poll editors, sidebar
use-canvas.ts All form state, validation, and submit logic
utils.ts CanvasState type, newPoll factory, MAX_CHARITIES
event-content/ Event view page composition
index.tsx JSX — two-column layout wiring all sub-components
use-event-content.ts pledgeAmount, pollSelections, addItemHandler
pledge-card/ Pledge confirmation card (right sidebar)
index.tsx JSX — amount input, breakdown, confirm button
use-pledge.ts All pledge state, validation, and submit handlers
amount-input.tsx £-prefixed numeric input
amount-presets.tsx Quick-select amount buttons
pledge-breakdown.tsx Itemised cost breakdown
utils.ts GBP formatter, fund colour constants, formatCharityLabel
poll-section/ Individual poll with pledge/results toggle
index.tsx JSX — ranking toggle, RankingList, PledgePanel
use-poll-section.ts view state, rankingView state, hasPledged transition
ranking-list/ Sorted ranking bars with live updates
index.tsx JSX — ordered list with animated bars
use-ranking-items.ts Supabase real-time subscription and re-sort logic
utils.ts rankItems, formatAmount, RankedItem type
ui/ shadcn/ui primitives
button.tsx, tabs.tsx, popover.tsx, toggle.tsx, …
charity-banner.tsx Charity logos with per-charity raised amount
event-hero.tsx Person photo, name, years, bio (view + edit modes)
pledge-panel.tsx Item selection chips and allocation display
stripe-checkout.tsx Stripe Elements payment modal
pot-banner.tsx Shared donation pot display
countdown.tsx Live closing countdown
home-carousel.tsx Homepage event showcase
lib/
email.ts Resend — pledge confirmation emails
occasions.ts OCCASION_LABELS, OCCASION_PLACEHOLDERS
supabase/ Admin and browser Supabase clients
utils.ts cn() and shared utilities
types/
index.ts All TypeScript types
scripts/
seed.ts Populates charities and topics
persons — the person being celebrated
| Column | Type | Notes |
|---|---|---|
| id | uuid | PK |
| name | text | |
| bio | text | |
| birth_year | int | |
| death_year | int | |
| photo_url | text | |
| created_by | text | Clerk user ID |
events — the main event record
| Column | Type | Notes |
|---|---|---|
| id | uuid | PK |
| person_id | uuid | FK → persons |
| occasion | text | memorial / birthday / retirement / wedding / other |
| created_by | text | Clerk user ID |
| closes_at | timestamptz | |
| is_private | bool |
event_charities — up to 3 charities per event
| Column | Type | Notes |
|---|---|---|
| event_id | uuid | FK → events |
| charity_id | uuid | FK → charities |
| display_order | int |
charities
| Column | Type | Notes |
|---|---|---|
| id | uuid | PK |
| name | text | |
| description | text | |
| logo_url | text | |
| registered_number | text |
topics — poll questions (curated or organiser-created)
| Column | Type | Notes |
|---|---|---|
| id | uuid | PK |
| title | text | e.g. "Favourite biscuit" |
| is_finite | bool | finite = fixed options; infinite = open-ended |
| created_by | text |
topic_items — options within a topic
| Column | Type | Notes |
|---|---|---|
| id | uuid | PK |
| topic_id | uuid | FK → topics |
| label | text | e.g. "Custard Cream" |
| is_master | bool | curated vs. user-added |
| all_time_pledged | numeric | running total across all events |
| all_time_count | int | times selected across all events |
event_polls — a topic attached to an event with optional personal framing
| Column | Type | Notes |
|---|---|---|
| id | uuid | PK |
| event_id | uuid | FK → events |
| topic_id | uuid | FK → topics |
| personal_framing | text | e.g. "Belinda's favourite was always the Lake District — what's yours?" |
| personal_quote | text |
event_poll_items — curated item selection for infinite topics
| Column | Type | Notes |
|---|---|---|
| event_poll_id | uuid | FK → event_polls |
| topic_item_id | uuid | FK → topic_items |
| is_guest_added | bool | |
| added_by | text | Clerk user ID |
pledges
| Column | Type | Notes |
|---|---|---|
| id | uuid | PK |
| event_poll_id | uuid | FK → event_polls |
| clerk_user_id | text | null for guest pledges |
| guest_email | text | null for signed-in pledges |
| guest_token | uuid | one-time withdrawal token; nulled after use |
| total_amount | numeric | in GBP |
| fee | numeric | 3% processing fee |
| withdrawn_at | timestamptz | null if active |
Check constraint: clerk_user_id IS NOT NULL OR guest_email IS NOT NULL
pledge_allocations — how a pledge is split across items
| Column | Type | Notes |
|---|---|---|
| pledge_id | uuid | FK → pledges |
| topic_item_id | uuid | FK → topic_items |
| amount | numeric |
event_pots — optional shared donation pool
| Column | Type | Notes |
|---|---|---|
| event_id | uuid | FK → events |
| total_deposited | numeric | |
| total_allocated | numeric |
pot_allocations — amounts assigned to individual guests
| Column | Type | Notes |
|---|---|---|
| pot_id | uuid | FK → event_pots |
| allocated_to | text | Clerk user ID |
| amount | numeric |
Finite topics have a fixed, pre-curated list of options (e.g. colours, seasons). All items come from topic_items where is_master = true.
Infinite topics have an open-ended list (e.g. films, songs, holiday destinations). Organisers curate a starting set when setting up the poll; guests can add their own during pledging. Items are stored in event_poll_items joined to topic_items.
Create .env.local at the project root:
# Clerk — https://dashboard.clerk.com
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_...
CLERK_SECRET_KEY=sk_test_...
CLERK_WEBHOOK_SECRET=whsec_...
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/
NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/
# Supabase — https://supabase.com/dashboard
NEXT_PUBLIC_SUPABASE_URL=https://...supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJ...
SUPABASE_SERVICE_ROLE_KEY=eyJ...
# Stripe — https://dashboard.stripe.com
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_...
STRIPE_SECRET_KEY=sk_test_...
# Resend — https://resend.com
RESEND_API_KEY=re_...
[email protected]
NEXT_PUBLIC_BASE_URL=https://yourdomain.com
# Install dependencies
pnpm install
# Start the dev server (Turbopack)
pnpm dev
App runs at http://localhost:3000.
The seed script populates the initial charity and topic data:
pnpm seed
This inserts:
Run seed once after setting up the database. Re-running is safe (uses upsert).
Clerk handles all auth. Protected routes call auth() from @clerk/nextjs/server and redirect to /sign-in if there is no session.
Webhook sync — POST /api/webhooks/clerk receives user.created, user.updated, and user.deleted events from Clerk and mirrors the user record into Supabase. Configure the webhook endpoint in the Clerk dashboard pointing to /api/webhooks/clerk.
POST /api/stripe/payment-intent with the amount in GBPPaymentIntent and returns the clientSecretcreatePledge server action records the pledge and allocations in Supabase and updates all_time_pledged on the relevant topic_itemsA 3% processing fee is added on top of the pledged amount and shown to the guest before confirmation.
pnpm build # Production build
pnpm start # Start production server
pnpm lint # ESLint
pnpm typecheck # tsc --noEmit
pnpm format # Prettier (all .ts/.tsx files)