You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fastgo Scooty is a modern, eco-friendly electric scooter rental application built with SwiftUI and powered by Supabase. This project implements the UI/UX design concept by Orbix Studio on Behance, focusing on a seamless user experience for urban mobility.
π± Features
Based on the Fastgo Scooty design specifications, the app includes:
Feature
Status
Description
Phone OTP Authentication
β
Sign in with phone number + SMS OTP via Supabase
Onboarding Flow
β
3-page intro screens for new users
User Profile Management
β
Name, gender, DOB, profile picture upload
Interactive Map
β
MapKit integration with real-time location
Scooter Discovery
β
View nearby available scooters on map
Scooter Details Sheet
β
Battery, range, pricing info in bottom sheet
Navigation to Scooter
β
Route polyline with ETA & distance
QR Code Scanner
β
Camera-based QR scanning to unlock scooter
Ride Reservation
β
10-minute free reservation with countdown timer
Ride In-Progress
β
Live ride tracking with parking spots displayed
Parking Navigation
β
Navigate to designated parking areas
Ride Completion
β
Finish ride flow with instructions
Ride History
β
View past rides and trip details
Promo Codes
β
Apply promotional discounts
Photo Verification
β
Submit a photo of your parked scooter for completing ride
Run this SQL in the Supabase SQL Editor for creating a table Users:
CREATE TABLE users (
id UUID PRIMARY KEY REFERENCES auth.users(id) ON DELETE CASCADE,
phone VARCHAR(20) UNIQUE NOT NULL,
name VARCHAR(100),
gender VARCHAR(20),
about_me VARCHAR(100),
date_of_birth DATE,
profile_image TEXT,
total_rides INTEGER NOT NULL DEFAULT 0,
total_distance DECIMAL(10,2) NOT NULL DEFAULT 0.0,
user_status JSONB NOT NULL DEFAULT '{"basic_info_completed": false}'::jsonb,
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
);
For Adding RLS Policy for Users Table:
ALTER TABLE users ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Users can read their own profile"
ON users
FOR SELECT
USING (auth.uid() = id);
CREATE POLICY "Users can insert their own profile"
ON users
FOR INSERT
WITH CHECK (auth.uid() = id);
CREATE POLICY "Users can update their own profile"
ON users
FOR UPDATE
USING (auth.uid() = id)
WITH CHECK (auth.uid() = id);
CREATE POLICY "Users can delete their own profile"
ON users
FOR DELETE
USING (auth.uid() = id);
Run this SQL in the Supabase SQL Editor for creating a table Rides:
CREATE TYPE ride_status AS ENUM (
'reserved',
'in_progress',
'completed',
'cancelled'
);
CREATE TABLE rides (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL
REFERENCES users(id)
ON DELETE CASCADE,
scooter_id UUID NOT NULL
REFERENCES scooters(id),
status ride_status NOT NULL DEFAULT 'reserved',
-- Start
start_latitude DOUBLE PRECISION NOT NULL,
start_longitude DOUBLE PRECISION NOT NULL,
start_location_name TEXT,
started_at TIMESTAMPTZ,
-- End (nullable until ride finishes)
end_latitude DOUBLE PRECISION,
end_longitude DOUBLE PRECISION,
end_location_name TEXT,
ended_at TIMESTAMPTZ,
-- Metrics
duration_minutes INT CHECK (duration_minutes >= 0),
distance_km DECIMAL(10,2) CHECK (distance_km >= 0),
-- Billing
base_fare DECIMAL(10,2) NOT NULL DEFAULT 0,
time_fare DECIMAL(10,2) NOT NULL DEFAULT 0,
total_fare DECIMAL(10,2) NOT NULL DEFAULT 0,
promo_code TEXT,
discount_amount DECIMAL(10,2) DEFAULT 0,
ride_completed_photo_url TEXT NULL;
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
For Adding RLS Policy for Rides Table:
CREATE POLICY "Users can view their rides"
ON rides
FOR SELECT
USING (user_id = auth.uid());
CREATE POLICY "Users can create rides"
ON rides
FOR INSERT
WITH CHECK (user_id = auth.uid());
CREATE POLICY "Users can update active rides"
ON rides
FOR UPDATE
USING (
user_id = auth.uid()
AND status IN ('reserved', 'in_progress')
)
WITH CHECK (
user_id = auth.uid()
);
Run this SQL in the Supabase SQL Editor for creating a table Scooters:
CREATE TABLE scooters (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
unique_code VARCHAR(50) UNIQUE NOT NULL, -- QR code value
type scooter_type NOT NULL,
battery INTEGER NOT NULL CHECK (battery BETWEEN 0 AND 100),
range_km INTEGER NOT NULL CHECK (range_km >= 0),
per_min_cost DECIMAL(10,2) NOT NULL,
image_name TEXT NOT NULL,
latitude DOUBLE PRECISION NOT NULL,
longitude DOUBLE PRECISION NOT NULL,
status scooter_status NOT NULL DEFAULT 'available',
last_seen_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
For Adding RLS Policy for Scooters Table:
ALTER TABLE scooters ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Public can view available scooters"
ON scooters
FOR SELECT
USING (status = 'available');
CREATE POLICY "No direct scooter updates"
ON scooters
FOR UPDATE
USING (false);
Run this SQL in the Supabase SQL Editor for creating a table Parking:
create table parking (
id uuid primary key default gen_random_uuid(),
name text not null,
latitude double precision not null,
longitude double precision not null,
created_at timestamp with time zone default now()
);
For Adding RLS Policy
alter table parking enable row level security;
create policy "Allow read access"
on parking
for select
using (true);
Run this SQL in the Supabase SQL Editor for creating a table Payments:
create table payment_methods (
id TEXT PRIMARY KEY,
user_id UUID REFERENCES auth.users(id) NOT NULL,
type TEXT NOT NULL CHECK (type IN ('bank', 'card')),
card_number TEXT,
card_holder_name TEXT,
expiry_date TEXT,
cvv TEXT,
bank_name TEXT,
account_number TEXT,
ifsc_code TEXT,
created_at TIMESTAMPTZ DEFAULT NOW()
);
For Adding RLS Policy
ALTER TABLE payment_methods ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Users can view their payment methods"
ON payment_methods FOR SELECT
USING (user_id = auth.uid());
CREATE POLICY "Users can insert payment methods"
ON payment_methods FOR INSERT
WITH CHECK (user_id = auth.uid());
CREATE POLICY "Users can delete their payment methods"
ON payment_methods FOR DELETE
USING (user_id = auth.uid());
Additional Setup :
Enable Phone Auth in Supabase Authentication settings and selectr Twilio as SMS provider. Add your Twilio Account SID , Twilio Auth Token & Twilio Message Service SID.
Create a storage bucket named avatars for profile images
Enable RLS Policy for 'avatars' bucket
CREATE POLICY "Users can upload their own avatar"
ON storage.objects
FOR INSERT
TO authenticated
WITH CHECK (
bucket_id = 'avatars'
AND auth.uid()::text = split_part(name, '/', 1)
);
CREATE POLICY "Public read access for avatars"
ON storage.objects
FOR SELECT
USING (bucket_id = 'avatars');
CREATE POLICY "Users can update their own avatar"
ON storage.objects
FOR UPDATE
TO authenticated
USING (
bucket_id = 'avatars'
AND auth.uid()::text = split_part(name, '/', 1)
);
Create a storage bucket named completedRides for profile images
Enable RLS Policy for 'completedRides' bucket
CREATE POLICY "Users can upload their own ride completion photo"
ON storage.objects
FOR INSERT
TO authenticated
WITH CHECK (
bucket_id = 'completedRides'
AND auth.uid()::text = split_part(name, '/', 1)
);
CREATE POLICY "Public read access for completed rides"
ON storage.objects
FOR SELECT
USING (bucket_id = 'completedRides');
CREATE POLICY "Users can update their own ride completion photo"
ON storage.objects
FOR UPDATE
TO authenticated
USING (
bucket_id = 'completedRides'
AND auth.uid()::text = split_part(name, '/', 1)
);