-
Notifications
You must be signed in to change notification settings - Fork 111
Feature: creator availability status #210
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
5ebed97
53c352c
31fa291
feea541
f6a4fe6
b30dfef
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| -- ================================================ | ||
| -- AVAILABILITY STATUS FEATURE - DATABASE SETUP | ||
| -- ================================================ | ||
| -- Run this ENTIRE script in your Supabase SQL Editor | ||
| -- Go to: https://supabase.com/dashboard → Your Project → SQL Editor → New Query | ||
| -- Copy and paste this entire file, then click "Run" | ||
| -- ================================================ | ||
|
|
||
| -- Step 1: Add the new columns to users table | ||
| ALTER TABLE public.users | ||
| ADD COLUMN IF NOT EXISTS availability_status TEXT DEFAULT 'available', | ||
| ADD COLUMN IF NOT EXISTS availability_message TEXT DEFAULT NULL; | ||
|
|
||
| -- Step 2: Add validation constraint | ||
| -- Drop existing constraint if it exists (in case you're re-running this) | ||
| ALTER TABLE public.users DROP CONSTRAINT IF EXISTS check_availability_status; | ||
|
|
||
| -- Add the constraint with valid values | ||
| ALTER TABLE public.users | ||
| ADD CONSTRAINT check_availability_status | ||
| CHECK (availability_status IN ('available', 'busy', 'not_looking')); | ||
|
|
||
| -- Step 3: Create index for faster filtering | ||
| CREATE INDEX IF NOT EXISTS idx_users_availability | ||
| ON public.users(availability_status); | ||
|
|
||
| -- Step 4: Add helpful comments for documentation | ||
| COMMENT ON COLUMN public.users.availability_status IS | ||
| 'Creator availability status: available (open for work), busy (booked but visible), not_looking (hidden from search)'; | ||
|
|
||
| COMMENT ON COLUMN public.users.availability_message IS | ||
| 'Optional custom message shown to brands (max 150 chars). Example: "Available starting January 2026"'; | ||
|
|
||
| -- Step 5: Update existing users to have default availability | ||
| -- This ensures all existing creators show as "available" by default | ||
| UPDATE public.users | ||
| SET availability_status = 'available' | ||
| WHERE availability_status IS NULL; | ||
|
|
||
| -- ================================================ | ||
| -- VERIFICATION: Check if it worked | ||
| -- ================================================ | ||
| -- After running the above, run this query to verify: | ||
| -- SELECT id, username, availability_status, availability_message FROM public.users LIMIT 5; | ||
|
|
||
| -- ================================================ | ||
| -- SUCCESS! | ||
| -- ================================================ | ||
| -- You should see: | ||
| -- ✓ availability_status column added | ||
| -- ✓ availability_message column added | ||
| -- ✓ All existing users set to 'available' | ||
| -- | ||
| -- Now refresh your frontend and the feature will work! | ||
| -- ================================================ | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| -- Add availability status to users table | ||
| ALTER TABLE public.users | ||
| ADD COLUMN IF NOT EXISTS availability_status TEXT DEFAULT 'available', | ||
| ADD COLUMN IF NOT EXISTS availability_message TEXT DEFAULT NULL; | ||
|
|
||
| -- Add check constraint to ensure valid status values | ||
| ALTER TABLE public.users | ||
| ADD CONSTRAINT check_availability_status | ||
| CHECK (availability_status IN ('available', 'busy', 'not_looking')); | ||
|
Comment on lines
+7
to
+9
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. CHECK constraint will fail on re-run. The Consider using this safer pattern: -- Add check constraint to ensure valid status values
-ALTER TABLE public.users
-ADD CONSTRAINT check_availability_status
-CHECK (availability_status IN ('available', 'busy', 'not_looking'));
+DO $$
+BEGIN
+ IF NOT EXISTS (
+ SELECT 1 FROM pg_constraint
+ WHERE conname = 'check_availability_status'
+ ) THEN
+ ALTER TABLE public.users
+ ADD CONSTRAINT check_availability_status
+ CHECK (availability_status IN ('available', 'busy', 'not_looking'));
+ END IF;
+END $$;Or use ALTER TABLE public.users DROP CONSTRAINT IF EXISTS check_availability_status;
ALTER TABLE public.users ADD CONSTRAINT check_availability_status
CHECK (availability_status IN ('available', 'busy', 'not_looking'));🤖 Prompt for AI Agents |
||
|
|
||
| -- Add index for faster filtering | ||
| CREATE INDEX IF NOT EXISTS idx_users_availability ON public.users(availability_status); | ||
|
|
||
| -- Add comment for documentation | ||
| COMMENT ON COLUMN public.users.availability_status IS 'Creator availability: available, busy, or not_looking'; | ||
| COMMENT ON COLUMN public.users.availability_message IS 'Optional custom message shown to brands (e.g., "Available starting Jan 2026")'; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,115 @@ | ||
| import { CheckCircle, Clock, XCircle } from 'lucide-react'; | ||
|
|
||
| type AvailabilityStatus = 'available' | 'busy' | 'not_looking'; | ||
|
|
||
| interface AvailabilityBadgeProps { | ||
| status: AvailabilityStatus; | ||
| message?: string | null; | ||
| size?: 'sm' | 'md' | 'lg'; | ||
| showMessage?: boolean; | ||
| } | ||
|
|
||
| /** | ||
| * AvailabilityBadge displays a color-coded badge showing creator availability status. | ||
| * @param status - The availability status (available/busy/not_looking) | ||
| * @param message - Optional custom message to display below badge | ||
| * @param size - Badge size variant (sm/md/lg) | ||
| * @param showMessage - Whether to display the custom message | ||
| */ | ||
| export default function AvailabilityBadge({ | ||
| status, | ||
| message, | ||
| size = 'md', | ||
| showMessage = true | ||
| }: AvailabilityBadgeProps) { | ||
| /** | ||
| * Returns styling configuration based on availability status. | ||
| */ | ||
| const getConfig = () => { | ||
| switch (status) { | ||
| case 'available': | ||
| return { | ||
| icon: CheckCircle, | ||
| label: 'Available', | ||
| bgColor: 'bg-green-100', | ||
| textColor: 'text-green-700', | ||
| borderColor: 'border-green-300', | ||
| dotColor: 'bg-green-500' | ||
| }; | ||
| case 'busy': | ||
| return { | ||
| icon: Clock, | ||
| label: 'Busy', | ||
| bgColor: 'bg-yellow-100', | ||
| textColor: 'text-yellow-700', | ||
| borderColor: 'border-yellow-300', | ||
| dotColor: 'bg-yellow-500' | ||
| }; | ||
| case 'not_looking': | ||
| return { | ||
| icon: XCircle, | ||
| label: 'Not Available', | ||
| bgColor: 'bg-gray-100', | ||
| textColor: 'text-gray-600', | ||
| borderColor: 'border-gray-300', | ||
| dotColor: 'bg-gray-500' | ||
| }; | ||
| default: | ||
| return { | ||
| icon: CheckCircle, | ||
| label: 'Available', | ||
| bgColor: 'bg-green-100', | ||
| textColor: 'text-green-700', | ||
| borderColor: 'border-green-300', | ||
| dotColor: 'bg-green-500' | ||
| }; | ||
| } | ||
| }; | ||
|
|
||
| /** | ||
| * Returns Tailwind CSS classes for the specified badge size. | ||
| */ | ||
| const getSizeClasses = () => { | ||
| switch (size) { | ||
| case 'sm': | ||
| return { | ||
| badge: 'px-2 py-0.5 text-xs', | ||
| icon: 'h-3 w-3', | ||
| dot: 'h-2 w-2' | ||
| }; | ||
| case 'lg': | ||
| return { | ||
| badge: 'px-4 py-2 text-base', | ||
| icon: 'h-5 w-5', | ||
| dot: 'h-3 w-3' | ||
| }; | ||
| default: // md | ||
| return { | ||
| badge: 'px-3 py-1 text-sm', | ||
| icon: 'h-4 w-4', | ||
| dot: 'h-2.5 w-2.5' | ||
| }; | ||
| } | ||
| }; | ||
|
|
||
| const config = getConfig(); | ||
| const sizeClasses = getSizeClasses(); | ||
| const Icon = config.icon; | ||
|
|
||
| return ( | ||
| <div className="inline-flex flex-col gap-1"> | ||
| <span | ||
| className={`inline-flex items-center gap-1.5 rounded-full font-medium border ${config.bgColor} ${config.textColor} ${config.borderColor} ${sizeClasses.badge}`} | ||
| > | ||
| <span className={`${config.dotColor} rounded-full ${sizeClasses.dot} animate-pulse`}></span> | ||
| <Icon className={sizeClasses.icon} /> | ||
| {config.label} | ||
| </span> | ||
| {showMessage && message && ( | ||
| <span className="text-xs text-gray-600 italic px-2"> | ||
| "{message}" | ||
| </span> | ||
| )} | ||
| </div> | ||
| ); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Constraint may fail on existing data with NULL values.
The CHECK constraint is added before the UPDATE that sets NULL values to 'available'. If the table has existing rows, they will have NULL in the new column (PostgreSQL ADD COLUMN with DEFAULT doesn't backfill existing rows in older versions). The constraint will reject NULL values, causing the migration to fail.
Reorder to update before adding the constraint:
🤖 Prompt for AI Agents