Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# ── Supabase ──────────────────────────────────────────────
# [SERVER] Your Supabase project URL (found in Project Settings → API)
# Copy the Project URL exactly as shown. Do not append `/rest/v1`.
NEXT_PUBLIC_SUPABASE_URL="https://your-project-ref.supabase.co"

# [SERVER] Your Supabase anon/public key (found in Project Settings → API)
# [SERVER] Your Supabase anon/public key
# Found in: Project Settings → API Keys → Legacy anon, service_role API keys
NEXT_PUBLIC_SUPABASE_ANON_KEY="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

# [CLIENT] Vite versions of the variables for browser-side OAuth and Auth flows.
Expand Down
20 changes: 15 additions & 5 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ DIRECT_URL="postgresql://postgres:[email protected]:5432/post

# ── Groq AI (optional) ───────────────────────
GROQ_API_KEY="gsk_your_groq_api_key"

# ── Supabase Service Role (for local auth setup) ──
SUPABASE_SERVICE_ROLE_KEY="your_supabase_service_role_key"
```

> **⚠️ Important:** Never commit your `.env` file. It is already in `.gitignore`.
Expand All @@ -116,13 +119,20 @@ npx prisma db push
npx prisma generate
```

### 5. Seed Demo Data
### 5. Setup Local Authentication & Seed Demo Data

Populate your database with realistic sneaker inventory, sales, expenses, price alerts, and market prices:
FlipTrack uses Supabase Auth, which requires registering the demo user in Supabase before seeding the database:

```bash
npx tsx prisma/seed.ts
```
1. **Create the demo user in Supabase Auth and sync to database:**
```bash
npx tsx scripts/create-demo-user.ts
```
*(Note: This uses the service role key to automatically confirm the user's email. If you did not configure it, you may need to confirm the email manually in the Supabase dashboard).*

2. **Seed the database with sample items, sales, and expenses:**
```bash
npx tsx prisma/seed.ts
```

### 6. Start the Dev Server

Expand Down
136 changes: 107 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,44 @@
<p><strong>Your Universal Reselling Empire, Tracked in Real Time.</strong></p>

<p>

<a href="https://github.com/rushikesh-bobade/FlipTrack/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="License: MIT"></a>
<a href="https://github.com/rushikesh-bobade/FlipTrack/pulls"><img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg" alt="PRs Welcome"></a>
<a href="https://reactrouter.com/"><img src="https://img.shields.io/badge/React_Router-v7-ca4245?logo=reactrouter" alt="React Router v7"></a>
<a href="https://supabase.com/"><img src="https://img.shields.io/badge/Database-Supabase-3ECF8E?logo=supabase" alt="Supabase"></a>
<a href="https://www.typescriptlang.org/"><img src="https://img.shields.io/badge/Language-TypeScript-3178C6?logo=typescript" alt="TypeScript"></a>

</p>

<p>

An open-source SaaS platform designed for resellers of <strong>any</strong> physical goods (electronics, vintage clothing, collectibles, streetwear, etc.) to manage their inventory, track market prices, and analyze their business using AI. Built to be a world-class, production-grade platform driven by the open-source community.

</p>

<p>

⭐ <strong>If you find FlipTrack useful or are participating in a hackathon, please consider giving this repository a star! It helps our open-source community grow.</strong> ⭐

</p>
</div>

<br />

## 📖 Table of Contents
- [Vision](#-vision)
- [Key Features](#-key-features)
- [Tech Stack Architecture](#-tech-stack-architecture)
- [Getting Started](#-getting-started)
- [Prerequisites](#prerequisites)
- [Local Installation](#local-installation)
- [Database Setup](#database-setup)
- [Local Development (Docker)](#local-development-docker)
- [Demo Credentials](#-demo-credentials)
- [Project Structure](#-project-structure)
- [Contributing](#-contributing)
- [License](#-license)

* [Vision](#-vision)
* [Key Features](#-key-features)
* [Tech Stack Architecture](#-tech-stack-architecture)
* [Getting Started](#-getting-started)
+ [Prerequisites](#prerequisites)
+ [Local Installation](#local-installation)
+ [Database Setup](#database-setup)
+ [Local Development (Docker)](#local-development-docker)
* [Demo Credentials](#-demo-credentials)
* [Project Structure](#-project-structure)
* [Contributing](#-contributing)
* [License](#-license)

---

Expand All @@ -48,15 +55,20 @@ Whether you are flipping 10 pairs a month or running a massive consignment opera
## 🌟 Key Features

* 📦 **Comprehensive Inventory Management**
Track every item with granular details including SKU, size, condition, purchase price, purchase date, and real-time status (`IN_STOCK`, `LISTED`, `SOLD`).
Track every item with granular details including SKU, size, condition, purchase price, purchase date, and real-time status ( `IN_STOCK` , `LISTED` , `SOLD` ).

* 📈 **Market Price Intelligence**
Automated background scraping (via API cron jobs) of real-time market prices across secondary platforms to keep your portfolio valuation accurate.

* 🧠 **Generative AI Insights**
Powered by the Vercel AI SDK and Groq (Llama 3), FlipTrack analyzes your inventory and provides actionable, data-driven advice on *when* to hold and *when* to sell.

* 💰 **Sales & Expense Tracking**
Log sales, track platform/shipping fees, and generate detailed P&L (Profit & Loss) statements instantly.

* 🔒 **Enterprise-Grade Authentication**
Secure login flows utilizing Supabase Auth with strict Server-Side Rendering (SSR) cookie validation.

* ✨ **Premium Glassmorphic UI**
A sleek, responsive, and blazing-fast interface built entirely from scratch utilizing raw CSS variables and CSS Modules, guaranteeing zero bloat from heavy UI frameworks.

Expand Down Expand Up @@ -93,18 +105,27 @@ Ensure you have the following installed and configured on your machine:
### Local Installation

1. **Clone the repository**
```bash


```bash
git clone https://github.com/rushikesh-bobade/FlipTrack.git
cd FlipTrack
```

2. **Install NPM dependencies**
```bash


```bash
npm install
```

3. **Configure Environment Variables**
Create a `.env` file in the root directory by copying `.env.example`.
Create a `.env` file in the root directory by copying `.env.example` .


```bash
cp .env.example .env
```

### Database Setup

Expand All @@ -114,12 +135,15 @@ You can set up your database using either a free cloud project or a local Postgr
1. Create a free project on [Supabase](https://supabase.com).
2. Copy your Project URL, Anon Key, and Database Connection Strings into your `.env` file.
3. Push the Prisma schema to your cloud database:
```bash


```bash
npx prisma db push
npx prisma generate
```

<a id="local-development-docker"></a>

### 🐳 Local Development (Docker)

**Option B: Local PostgreSQL via Docker (No Cloud Account Required)**
Expand All @@ -128,49 +152,103 @@ This is the recommended path for external contributors, since the project's live

1. Make sure [Docker](https://www.docker.com/) is installed and running.
2. Start the local Postgres container:
```bash


```bash
docker-compose up -d
```
This starts a `postgres:15` container named `fliptrack_postgres`, exposed on `localhost:5432`, with a persistent volume so your data survives restarts.

This starts a `postgres:15` container named `fliptrack_postgres` , exposed on `localhost:5432` , with a persistent volume so your data survives restarts.
3. In your `.env`, set `DATABASE_URL` and `DIRECT_URL` to the local connection string (already provided, commented out, in `.env.example`):
```bash


```bash
DATABASE_URL="postgresql://postgres:password@localhost:5432/fliptrack_dev"
DIRECT_URL="postgresql://postgres:password@localhost:5432/fliptrack_dev"
```

4. You can leave `NEXT_PUBLIC_SUPABASE_URL` and `NEXT_PUBLIC_SUPABASE_ANON_KEY` blank or mock them if you are only testing UI/Prisma logic.
5. Push the schema and generate migrations, all against your own local database:
```bash


```bash
npx prisma db push
npx prisma generate
npx prisma migrate dev --name your-migration-name
```

6. To stop the container (data is preserved in the Docker volume):
```bash


```bash
docker-compose down
```
To wipe the local database completely, add `-v`: `docker-compose down -v`.

To wipe the local database completely, add `-v` : `docker-compose down -v` .

### Start Development Server

Start the Vite development server:

```bash
npm run dev
```
The application will be running locally at `http://localhost:5173`.

The application will be running locally at `http://localhost:5173` .

---

## 🔐 Local Authentication

FlipTrack uses **Supabase Auth** for authentication, while the dashboard data is stored in Prisma-managed tables.

To link the two systems, the application relies on the `User` table in the database having a record where `id` matches the Supabase Auth user ID (UUID) of the logged-in user.

The local setup involves two separate scripts that must be run in the **exact order** below:

1. `scripts/create-demo-user.ts`:
* Creates/registers the demo user (defaults to `[email protected]`) in your Supabase Auth project.
* Retrieves the generated Supabase User ID (UUID) and creates/upserts a matching user record in the local database's `User` table using Prisma.
2. `prisma/seed.ts`:
* Queries the database for the demo user using the configured email.
* Populates the database with demo inventory items, sales, expenses, and other mock dashboard data under that user's ID.

> [!IMPORTANT]
> You **must** run the scripts in this order. If you run the seed script first, the data will be seeded under a temporary ID, and the subsequent user creation script will fail with unique email constraint errors or cause the logged-in user to see an empty dashboard.

---

## 💡 Demo Credentials

Want to test FlipTrack's UI and features without manually creating data? We have included an automated seed script that provisions a test user and sample inventory items.
Want to test FlipTrack's UI and features without manually creating data? We have included automated scripts to provision the demo user and sample inventory items.

### Environment Variable Requirements
Before running the scripts, ensure your `.env` file has:
* `NEXT_PUBLIC_SUPABASE_URL` and `NEXT_PUBLIC_SUPABASE_ANON_KEY`
* `DATABASE_URL` and `DIRECT_URL`
* `SUPABASE_SERVICE_ROLE_KEY` (Highly Recommended)
> [!NOTE]
> If `SUPABASE_SERVICE_ROLE_KEY` is provided, the script will automatically create a pre-confirmed user in Supabase Auth using admin privileges. If not, it falls back to the public sign-up API. If email confirmation is enabled in your Supabase project (default), you will need to manually confirm the user in your Supabase Dashboard (under Authentication → Users) to sign in.

1. Ensure your development server is running (`npm run dev`).
2. Execute the demo creation script:
### Setup Steps
1. Make sure your local PostgreSQL database (via Docker or local service) is running and your Prisma schema has been pushed:
```bash
npx prisma db push
npx prisma generate
```
2. Run the demo setup scripts in the correct order:
```bash
# 1. Create the user in Supabase and sync to database first
npx tsx scripts/create-demo-user.ts

# 2. Seed the inventory data under that user
npx tsx prisma/seed.ts
```
3. Start the development server:
```bash
npm run dev
```
3. Navigate to `http://localhost:5173/auth/login`.
4. Click the **"Use Demo Credentials"** button on the login form to instantly authenticate and view the populated dashboard.
4. Navigate to `http://localhost:5173/auth/login` and click the **"Use Demo Credentials"** button on the login form to instantly authenticate (using `[email protected]` / `password123`) and view the populated dashboard.

---

Expand Down
28 changes: 16 additions & 12 deletions app/blocks/login-page/login-form.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
import { Form, Link, useActionData, useSubmit } from "react-router";
import { Form, Link, useActionData, useNavigation } from "react-router";
import styles from "./login-form.module.css";
import { useRef } from "react";

interface Props { className?: string; }

export function LoginForm({ className }: Props) {
const actionData = useActionData<{ error?: string }>();
const submit = useSubmit();
const navigation = useNavigation();
const isSubmitting = navigation.state === "submitting";
const formRef = useRef<HTMLFormElement>(null);

const handleDemoLogin = () => {
if (formRef.current) {
const formData = new FormData(formRef.current);
formData.set("email", "[email protected]");
formData.set("password", "password123");
submit(formData, { method: "post" });
}
const form = formRef.current;
if (!form) return;

(form.elements.namedItem("email") as HTMLInputElement).value = "[email protected]";
(form.elements.namedItem("password") as HTMLInputElement).value = "password123";

form.requestSubmit();
};

return (
Expand All @@ -39,13 +41,15 @@ export function LoginForm({ className }: Props) {
<Link to="/auth/forgot-password" className={styles.forgotLink}>Forgot password?</Link>
</div>
<button type="submit" className={styles.submitBtn}>Sign In</button>
<button
type="button"
className={styles.submitBtn}
<button
type="button"
className={styles.submitBtn}
style={{ background: "transparent", border: "1px solid var(--color-border-strong)", marginTop: "var(--space-2)", color: "var(--color-text)" }}
onClick={handleDemoLogin}
disabled={isSubmitting}

>
Use Demo Credentials
{isSubmitting ? "Signing in..." : "Use Demo Credentials"}
</button>
</Form>
);
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 14 additions & 13 deletions prisma/seed.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,28 @@
import { PrismaClient, ItemStatus, ItemCondition, Marketplace, ExpenseType, Currency, Plan, Theme } from '@prisma/client';
import "dotenv/config";

const prisma = new PrismaClient();

async function main() {
console.log("Starting seed...");

let user = await prisma.user.findFirst();
const demoEmail = process.env.DEMO_USER_EMAIL || "[email protected]";

let user = await prisma.user.findUnique({
where: { email: demoEmail }
});

if (!user) {
user = await prisma.user.create({
data: {
email: "[email protected]",
name: "Demo User",
plan: Plan.PRO,
currency: Currency.USD,
theme: Theme.LIGHT
}
});
console.log("Created demo user:", user.email);
} else {
console.log("Using existing user:", user.email);
console.error(`\n❌ Error: Demo user with email "${demoEmail}" not found in the database.`);
console.error("To set up local authentication and seed the database correctly, you must run the user creation script first:");
console.error(" npx tsx scripts/create-demo-user.ts");
console.error("This will register the user in Supabase Auth and sync it to the database.");
console.error("Then, run this seed script again to populate the database with demo inventory data.\n");
process.exit(1);
}

console.log("Using existing user for seeding:", user.email);

// Clear existing data for this user to avoid unique constraint errors during re-seeds
await prisma.expense.deleteMany({ where: { userId: user.id } });
await prisma.sale.deleteMany({ where: { userId: user.id } });
Expand Down
Loading