Skip to content

lindestad/farm-connect

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

135 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FarmConnect

FarmConnect is a mobile-first marketplace that connects customers with local farms. Users can browse, reserve, and schedule pickups for fresh produce, while farmers manage inventory, pickup windows, and recurring market events-all in one streamlined platform.


Demo data note: The Supabase migrations include seeded demo farms in 202605050010_seed_demo_farms.sql and login-ready demo accounts in 202605111200_seed_full_demo_data.sql. Use these accounts to explore the customer and farmer flows:

Role Email Password
Customer [email protected] DemoPass123!
Farmer [email protected] DemoPass123!

View Progress (Features Implemented)
  • Demo Landing Page (feature showcase, customer/farmer flow overview, mock phone preview UI)
  • Authentication System (email/password login and registration, role selection, email confirmation redirect, forgot password / in-app reset flow)
  • Account System (customer profile: display name, phone, location, bio, contact preference, pickup notes; farmer account access control)
  • Farm Profile (create, view, edit, and delete farm profiles; owner-only controls)
  • Farmer Dashboard (role-gated dashboard with navigation to market and inventory management)
  • Market Day Management (full CRUD: create, edit, and delete market days with date/time pickers, location, notes, status filtering)
  • Pickup Inventory & Time Slots (farmer-managed per-pickup produce inventory with quantities, pricing, and available time slot windows)
  • Farm Stock Management (per-farm produce catalog with stock quantities and pricing; server-side stock decrement on order)
  • Produce Browser (browse produce list with Norwegian/English names; detail view with full nutritional info sourced from Matvaretabellen)
  • Map (Google Maps integration with searchable farm list sidebar; tap a result to pan the map to that farm)
  • Camera (in-app camera capture, image preview, retake, confirm, and upload to Supabase Storage)
  • Payment System (Stripe test mode via Supabase Edge Function; order screen with payment sheet, Google Pay support)
  • Customer Order History (view past pickup and reservation orders with order items and timestamps)
  • Push Notifications (Expo Push API via FCM; notifies customer on payment confirmation and reservation placement)

Supabase Instructions

For email confirmation and password reset links to return to the app, add these redirect URLs in the Supabase dashboard:

farmconnect://auth/confirm
farmconnect://auth/reset-password

The current auth flow includes:

  • Registration with email/password
  • Profile role selection for customer or farmer
  • Login with email/password
  • Persisted mobile sessions
  • Email confirmation redirect back into the app
  • Forgot password email with in-app reset flow

Migrations are in supabase/migrations/ and applied in timestamp order. See supabase/migrations/migrations.md for the full workflow (applying, dry-run, repair).


Stripe Instructions

The app uses Stripe for payment processing via the @stripe/stripe-react-native SDK. Payments are handled through a Supabase Edge Function (create-payment-intent) which creates a Stripe PaymentIntent server-side, keeping the secret key off the client. A second edge function (decrement-stock) handles server-side stock decrement on order completion. Both edge functions are deployed to Supabase. To test a payment, use the following Stripe test card:

Field Value
Number 4242 4242 4242 4242
Expiry 05/55
CVC 555

Generate Produce Data

Run this script to generate produceData.json from Matvaretabellen data and the curated produce list in src/data/produceList.ts.

Each produce item in src/data/produceList.ts must include a foodId that matches the correct Matvaretabellen entry. This foodId is used as the stable reference when generating product data. New items must therefore be matched manually in Matvaretabellen before they are added to the list.

Input: src/data/produceList.ts

Run the script from the project root:

npx tsx scripts/generateProductData.ts

This regenerates: src/data/produceData.json


Camera functionality

src/components/CameraCapture.tsx handles:

  • camera permission
  • camera preview
  • taking a picture
  • previewing the image
  • retaking the image
  • confirming the image

src/lib/image-helpers/image-create.ts handles uploading images src/lib/image-helpers/image-delete.ts handles deleting images

How to use the camera functionality in another screen:

import CameraCapture from "@/components/CameraCapture";

Then create a function that receives the confirmed image URI. This runs after the user presses Use Photo.

const handlePhotoConfirmed = async (uri: string) => {
  // Do something with the image URI here.
};

If the image should be uploaded immediately, call the upload helper inside that function:

import uploadConfirmedImage from "@/lib/image-helpers/image-create";

const handlePhotoConfirmed = async (uri: string) => {
  const { imageUrl, imagePath } = await uploadConfirmedImage(uri);

  // imageUrl is the public URL for showing the uploaded image.
  // imagePath is the file path used to locate or delete the image in Storage later.
};

Finally, render the camera component and pass the function to onPhotoConfirmed.

return <CameraCapture onPhotoConfirmed={handlePhotoConfirmed} />;

Push Notifications

Push notifications are delivered via the Expo Push API backed by Firebase Cloud Messaging (FCM). This only works on native Android builds, not Expo Go or web.

On login, the app registers an Expo push token stored in push_tokens. After checkout creates an order, the client calls the notify-payment-success edge function with the user's session JWT, and the function sends the appropriate notification.

google-services.json is required in the project root for native builds and is tracked in this repo. It contains public Firebase client identifiers; service account credentials are managed separately through EAS credentials.

Event Recipient Title Body
Pickup order placed Customer Payment confirmed Your payment of {amount} NOK was successful.
Reservation placed Customer Reservation confirmed Your items are reserved and held for 48 hours. Pay at pickup.

Getting Started

See CONTRIBUTING for setup instructions and how to contribute.


Tech Stack

Layer Technology
Framework React Native (Expo)
Routing Expo Router
Backend Supabase (Auth, Database, Edge Functions)
Payments Stripe (@stripe/stripe-react-native)
Maps Google Maps (react-native-maps)
Language TypeScript

Quality Checks

CI runs on every pull request and push to main. Recommended to install Prettier extension. You can run the checks locally:

npm run lint          # ESLint
npm run typecheck     # TypeScript
npm run format:check  # Prettier
npm test              # Jest (with coverage)
npm audit             # Dependency security audit

Or run all checks at once:

./quality-check.sh

CI also enforces a console.log-free codebase, remove any console.log calls before merging.

About

No description, website, or topics provided.

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors