A modern, full-stack partner directory and showcase platform built with Next.js and Supabase. This application demonstrates advanced features including PostgreSQL full-text search, image optimization with Supabase Storage, and serverless email notifications via Edge Functions.
- Full-Text Search: PostgreSQL
tsvectorimplementation for fast, relevance-based partner search - Partner Gallery: Categorized display of technology partners and expert agencies
- Image Management: Optimized image storage and delivery using Supabase Storage with Next.js Image optimization
- Contact Forms: Integrated partner application forms with serverless email notifications
- Dark Mode: Built-in theme switching support
- Responsive Design: Mobile-first design with Tailwind CSS
- Type Safety: Full TypeScript implementation for enhanced developer experience
- Next.js 12 - React framework with SSR and static generation
- React 17 - UI library
- TypeScript - Type-safe JavaScript
- Tailwind CSS - Utility-first CSS framework
- Radix UI - Accessible component primitives
- Swiper - Touch-enabled carousel/slider
- Supabase - Backend-as-a-Service platform
- PostgreSQL database with Row Level Security
- Supabase Storage for image hosting
- Edge Functions (Deno) for serverless email processing
- Marked - Markdown parser for content rendering
- Node.js 16.x or higher
- npm or yarn package manager
- Supabase account and project
- SMTP server credentials (AWS SES recommended)
git clone <repository-url>
cd partner-directory-platformcd app
npm installCreate a .env.local file in the app directory:
NEXT_PUBLIC_SUPABASE_URL=your_supabase_project_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_keyThe database schema is defined in supabase/migrations/20230712074829_init.sql. Apply the migration:
supabase link --project-ref your-project-ref
supabase db pushThis creates:
partnerstable with full-text search capabilitiespartner_contactstable for form submissions- Row Level Security policies
- PostgreSQL
tsvectorindex for search
Deploy the email notification Edge Function:
# Link to your Supabase project
supabase link --project-ref your-project-ref
# Set environment variables
supabase secrets set \
SMTP_HOSTNAME="your.smtp.hostname.com" \
SMTP_PORT="2587" \
SMTP_USERNAME="your_smtp_username" \
SMTP_PASSWORD="your_smtp_password" \
SMTP_FROM="[email protected]" \
SMTP_TO="[email protected]" \
FUNCTION_SECRET="your-random-secret-key"
# Deploy the function
supabase functions deploy contact-notificationNote: The SMTP_PORT must be a port other than 25, 465, or 587 as Deno Deploy restricts outgoing connections to these ports. AWS SES (port 2587) is recommended.
Set up a Supabase Database Webhook to trigger the Edge Function when a new row is inserted into the partner_contacts table:
- Navigate to Database β Webhooks in your Supabase dashboard
- Create a new webhook
- Configure:
- Name:
contact-notification - Table:
partner_contacts - Events:
INSERT - HTTP Request:
POSTto your Edge Function URL - Headers:
x-function-secret: your-random-secret-key - Request body: Select the row data
- Name:
- Import your repository to Vercel
- Configure project settings:
- Framework Preset: Next.js
- Root Directory:
app
- Add environment variables:
NEXT_PUBLIC_SUPABASE_URLNEXT_PUBLIC_SUPABASE_ANON_KEY
- Deploy
.
βββ app/ # Next.js application
β βββ components/ # React components
β β βββ BecomeAPartner.tsx
β β βββ PartnerTileGrid.tsx
β β βββ ...
β βββ pages/ # Next.js pages and API routes
β β βββ index.tsx
β β βββ partners/
β βββ lib/ # Utility libraries
β β βββ supabase.ts
β β βββ theme.tsx
β βββ types/ # TypeScript type definitions
β βββ styles/ # Global styles
βββ supabase/
β βββ functions/ # Edge Functions
β β βββ contact-notification/
β βββ migrations/ # Database migrations
βββ README.md
The platform implements PostgreSQL full-text search using tsvector:
tsv tsvector generated always as (
setweight(to_tsvector('english', title), 'A')
|| setweight(to_tsvector('english', description), 'B')
|| setweight(to_tsvector('english', overview), 'C')
|| setweight(to_tsvector('english', category), 'D')
)Search queries can be performed using PostgreSQL's ts_rank and to_tsquery functions for relevance-based results.
Theme colors and styling can be customized in:
app/tailwind.config.js- Tailwind configurationapp/ui.config.js- Theme variablesapp/default-colors.js- Color definitions
Partner categories are dynamically generated from the database. Update the category field in the partners table to add or modify categories.
Partners can be added directly to the database:
INSERT INTO partners (
slug, type, category, developer, title, description,
logo, overview, website, docs, contact
) VALUES (
'partner-slug', 'technology', 'Category Name', 'Developer Name',
'Partner Title', 'Brief description', 'logo-url',
'Detailed overview', 'https://website.com', 'https://docs.com',
contact_id
);Or through the "Become a Partner" form, which creates a contact record for review.
- Row Level Security (RLS): Enabled on all tables with appropriate policies
- Public Read Access: Partners table allows public reads for approved partners
- Protected Writes: Contact submissions require no authentication but are validated
- Function Security: Edge Functions protected with secret headers
This project is licensed under the MIT License.
Contributions are welcome! Please feel free to submit a Pull Request.