Easy-to-manage touch screens
Free, open-source touch screens. Guided USB setup, a drag-and-drop editor and local control. Made for Home Assistant.
Find a seat in a car going your way across Islamabad and Rawalpindi, or between cities all over Pakistan. Or offer the empty seats in yours.
LifestyleTypeScript · CSSGitHub @muhammadammar33OnlineOwner 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
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗Live at hamsafar.website.
Right now Hamsafar is a carpool site: city rides across Islamabad, Rawalpindi, Wah, Taxila and Rawat, and rides between cities all over Pakistan. Drivers offer the empty seats in their car without signing up; riders search by pickup and drop-off and book a seat. The organisations platform described further down (vans, universities, tours, companies) is still in the code and still works, but it's hidden from the home page for now.
/me) lists their rides (with the manage page) and upcoming bookings, and a ride page shows their ticket.GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET are set; until then the site works without accounts. Private manage links keep working either way.state and nonce; the ID token's signature, issuer, audience, expiry and verified email are checked; sessions are signed, HttpOnly cookies (180 days); sign-out is a POST; return paths are limited to this site. Setting users.blocked_at blocks an account./privacy and terms /terms links, audience External, then Publish) → Clients → Create client → Web application, authorized redirect URI https://hamsafar.website/api/auth/google/callback → put the client ID and secret in Vercel and redeploy.CITY_AREA in lib/cities.ts), chosen from about 80 local places or a pin. Riders match when the route passes within about 3 km of their pickup and drop-off.?kind=intercity; old links without it are guessed from the places)./privacy explains all of this./offer, or /offer?kind=intercity): in the city or between cities, then the starting point, any stops on the way, final destination. Each comes from the list of places (or cities), or from "use my current location", or from a pin dropped on the map./r/manage/<token>), which they can also send to their own WhatsApp. It shows who booked each day (call / WhatsApp / remove) and lets them edit, pause, resume or cancel the ride and share their live location while driving. The link is the only key: anyone who has it can manage the ride. This browser also remembers the rides it created ("Your rides" on the home page)./ or /search) with a pickup and a drop-off (from the list, current location, or a pin) and optionally a day./r/<slug>) shows the route on a map and the driver's live position. Book with name, phone and gender. The booking shows the driver's number with one-tap WhatsApp (message already written) and call. A seat can be cancelled from the same browser or with phone + booking code.Once WhatsApp is set up, offering a ride, booking a seat, and changing a driver's number all need a verified WhatsApp number (checked once per phone; the browser remembers it for 90 days). Two ways, either or both:
send): a 6-digit code arrives on WhatsApp with a "Copy code" button; typed in, it's checked (5 tries, 10 minutes, at most 5 codes per number per hour). Meta charges a small fee per code message.message, free): WhatsApp opens with "Hamsafar code 123456" ready to send to the business number; the message arriving from their number on the webhook proves it's theirs, and the page continues by itself.Setup (Meta for Developers → create an app → add WhatsApp):
WHATSAPP_PHONE_NUMBER_ID, WHATSAPP_TOKEN, and WHATSAPP_BUSINESS_NUMBER (digits with 92).hamsafar_otp, language English → WHATSAPP_OTP_TEMPLATE=hamsafar_otp.https://hamsafar.website/api/whatsapp/webhook, any verify token you choose (WHATSAPP_VERIFY_TOKEN), subscribe to messages; App settings → Basic → App secret → WHATSAPP_APP_SECRET.PHONE_VERIFICATION=off turns checks off again without deleting anything./feedback: idea, problem, safety concern or praise, from a rider, driver or anyone, with an optional name and phone/email for a reply. Linked from the home page, every ride page ("Problem with this ride?"), the driver's page and after a rating. Safety reports show the emergency numbers (15 Police, 1122 Rescue) first.| Path | Purpose |
|---|---|
/ | Search, "rides leaving soon", your rides, live map |
/search?from=&to=&date=&kind= | Matching rides on a map |
/offer | Offer a ride |
/r/<slug> | Public ride page and booking (the link to share) |
/r/manage/<token> | Driver's private page, with their rating |
/feedback | Send feedback to the Hamsafar team |
/privacy | Privacy notice (ID checks, location, phone numbers) |
/admin/verifications | Super admin: ID checks, notifications |
/admin/rides | Super admin: all carpool rides |
/admin/feedback | Super admin: feedback messages and driver reviews |
GET/POST /api/rides, /api/rides/<slug>[/book|/lookup|/cancel|/review], /api/rides/manage/<token>, /api/live, POST /api/feedback, POST /api/identity, GET /api/identity/status, /api/admin/id-docs/<id>, /api/admin/push | JSON API used by the pages |
The places list is in lib/places.ts, the cities in lib/cities.ts, ID rules and the card scan parser in lib/identityRules.ts, route matching in lib/geo.ts and schedules in lib/schedule.ts (npm test covers them). The maps are OpenStreetMap tiles drawn with Leaflet, and place names for dropped pins come from Nominatim. Neither needs an API key.
Its landing page is at /business (not linked or indexed). /admin, /o/<org>, /t/<code> and /d/<secret> all work as before.
Seat booking for every van, coaster and bus in Pakistan. An organisation shares one link in its WhatsApp group; passengers pick their stop, see the pickup time and choose a seat on a picture of the vehicle, with males and females seated apart.
Every client is an organisation with its own admins, vehicles, trips and (when it has one) list of registered riders. The type of organisation decides the wording and the default booking rules:
| Type | Riders | Default rules |
|---|---|---|
| 🚐 Van & coaster operator (private intercity vans) | Anyone with the link; different people every trip | Males and females apart, one seat per person |
| 🎓 University, college or school | Registered students only, from a list uploaded as Excel/CSV | Males and females apart; name and gender come from the list |
| 🏔️ Tour operator | Anyone; nothing kept after the trip | No male/female rule, a family books up to 6 seats together, multi-day dates and an itinerary |
| 🏢 Company staff transport | Registered employees only | Same as universities |
Every rule can be changed per trip (seating rule, seats per booking, registered-only).
| Path | Who | Purpose |
|---|---|---|
/business | Everyone | Organisations landing page (hidden): who it's for, a live seat-picking demo, public trips |
/o/<org> | Everyone | An organisation's page: contact details and its open trips / tours |
/t/<code> | Passengers | Book a seat (the link shared in WhatsApp) |
/d/<secret> | Driver | Passengers stop by stop, call / WhatsApp, mark boarded and paid |
/admin/orgs | Super admin | All organisations, platform totals, create organisation, super admins |
/admin/orgs/<id> | Super admin | Organisation details, admins, public page, open dashboard, switch off, delete |
/admin | Admin | Trips by day with seats and fares |
/admin/trips/new, /admin/trips/<id> | Admin | Create and run a trip: share links, seat map, passengers, booking rules |
/admin/riders | Admin (universities, companies) | Registered students / employees: import Excel or CSV, add, edit, switch off, export |
/admin/vehicles | Admin | Seating plans |
/admin/account | Admin | Team (admins of the organisation) and password |
Two people tapping the same seat at once: only the first gets it (bookings run in a locked database transaction).
DATABASE_URL)..env.example): AUTH_SECRET (32+ random characters), ADMIN_EMAIL and ADMIN_PASSWORD (the first super admin), optional SITE_URL, NEXT_PUBLIC_CONTACT_WHATSAPP, NEXT_PUBLIC_PLATFORM_NAME (default "Hamsafar"), NEXT_PUBLIC_TIMEZONE (default Asia/Karachi).scripts/db-setup.ts: migrations, default vehicles, first super admin.hamsafar.website (and www.hamsafar.website, redirecting to it).A / CNAME records and add the records Vercel shows, usually A @ 76.76.21.21 and CNAME www cname.vercel-dns.com.SITE_URL=https://hamsafar.website and redeploy. From then on, visits to the old *.vercel.app address are sent to hamsafar.website (proxy.ts), and link previews, robots.txt and sitemap.xml use the domain.Upgrading from the single-operator version: the migration creates one organisation holding all existing trips, vehicles and bookings, and makes every existing admin a super admin. If NEXT_PUBLIC_BRAND_NAME was set, that becomes the organisation's name. Sign in, open the organisation under Organisations, and add its own admin under Team.
npm install
cp .env.example .env.local # DATABASE_URL, AUTH_SECRET, ADMIN_EMAIL, ADMIN_PASSWORD
npm run db:setup
npm run dev
| Script | Purpose |
|---|---|
npm run dev / build / start | Develop / production build (runs db-setup) / serve |
npm test | Seat rules, rider-list parsing and formatting tests |
npm run lint / typecheck | ESLint / TypeScript |
npm run db:generate | New migration after changing lib/db/schema.ts |
app/ Pages: home, /o (organisation), /t (booking), /d (driver), /admin, /api
app/admin/actions.ts All admin actions; every one is limited to the admin's organisation
lib/orgTypes.ts Organisation types: wording and default rules
lib/layout.ts Vehicle grid, seat numbering, gender + neighbour rules
lib/trips.ts Loading trips, booking (locked transaction, groups, registered riders), lookup, cancel, driver
lib/riders.ts Excel/CSV rider list parsing and validation
lib/auth.ts Sessions, super admin vs organisation admin, current organisation
lib/db/schema.ts organizations, admins, riders, vehicles, trips, stops, bookings
drizzle/ SQL migrations