Skip to content

Commit 4f59b49

Browse files
committed
feat: enhance README and .env.example
1 parent a2d637d commit 4f59b49

12 files changed

+314
-16
lines changed

.env.example

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ NGROK_HOST='' # change this to your ngrok host
1212

1313
# Stripe
1414
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY='' # change this to your stripe publishable key
15+
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY_LIVE='' # change this to your stripe publishable live key
1516
STRIPE_SECRET_KEY='' # change this to your stripe secret key
1617
STRIPE_WEBHOOK_SECRET='' # change this to your stripe webhook secret
1718

README.md

+140-16
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,160 @@
1-
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
1+
# Pictoria AI - Personalized AI Photo Generation Platform
22

3-
## Getting Started
3+
Transform your photos with the power of AI! Pictoria AI is your ultimate solution for creating/generating professional AI-generated photos, similar to the popular PhotoAI platform. Perfect for LinkedIn headshots, Instagram content, dating profile pictures, and professional portraits. Train AI model on your personal images and generate stunning, high-quality AI-generated photos within minutes.
44

5-
First, run the development server:
5+
![GitHub stars](https://img.shields.io/github/stars/codebucks27/Pictoria-AI-Starter-Code?style=social&logo=ApacheSpark&label=Stars)  
6+
![GitHub forks](https://img.shields.io/github/forks/codebucks27/Pictoria-AI-Starter-Code?style=social&logo=KashFlow&maxAge=3600)  
7+
![Github Followers](https://img.shields.io/github/followers/codebucks27.svg?style=social&label=Follow)&nbsp;&nbsp;<br />
8+
9+
If you want to learn how to create it please follow below tutorial👇: <br />
10+
➡ Tutorial Link 💚: [How to Build a $1M PhotoAI Sass Clone using Next.js 15, Supabase, Replicate API and Stripe](https://youtu.be/7AQNeii5K7E)
11+
[![YouTube Video Views](https://img.shields.io/youtube/views/7AQNeii5K7E
12+
)](https://youtu.be/7AQNeii5K7E) <br />
13+
14+
15+
🎯 For customised solutions or deployment please contact: https://tally.so/r/wdlj0N
16+
17+
> NOTE: This is a final version of the project. Before you make it live, please make sure to test it thoroughly and make any necessary adjustments.
18+
19+
---
20+
# ⭐DO NOT FORGET TO STAR THIS REPO⭐
21+
---
22+
23+
## 🚀 Key Features
24+
---
25+
26+
- 🛠️ Complete SaaS built in modern Next.js
27+
- 💻 Beautiful landing page included
28+
- 🤖 Train AI model on your personal images
29+
- 🖥️ Clean & intuitive event monitoring dashboard
30+
- 🎯 AI-Powered Professional Photo Generation
31+
- 🎨 Custom AI Model Training
32+
- 💼 Professional LinkedIn Headshots
33+
- 🌟 Clean, modern UI on top of shadcn-ui
34+
- 📱 Social Media Content Generation
35+
- 💳 Integrated Payment System
36+
- ✉️ Email Notifications
37+
- 📊 Usage Analytics
38+
- 🎁 ...much more
39+
40+
## 🛠️ Tech Stack
41+
42+
- **Framework:** Next.js 15 (App Router)
43+
- **Styling:** Tailwind CSS, Shadcn UI
44+
- **Database:** Supabase (PostgreSQL)
45+
- **Authentication:** Supabase Auth
46+
- **AI Integration:** Replicate AI API
47+
- **Payment Processing:** Stripe
48+
- **Email Service:** Resend
49+
- **Language:** TypeScript
50+
51+
## ⚡ Prerequisites
52+
53+
Before you begin, ensure you have:
54+
55+
- Node.js installed (v20.x recommended, v18+ supported)
56+
- A Supabase account
57+
- A Replicate account
58+
- A Stripe account
59+
- A Resend account
60+
61+
## 🚀 Setup Instructions
62+
63+
### 1. Clone the Repository
64+
65+
```bash
66+
git clone [your-repo-url]
67+
cd Pictoria-AI-Starter-Code
68+
```
69+
70+
### 2. Install Dependencies
71+
72+
```bash
73+
npm install
74+
# or
75+
yarn install
76+
# or
77+
pnpm install
78+
```
79+
80+
### 3. Environment Variables
81+
82+
Create a `.env.local` file in the root directory. Check `.env.example` for required variables.
83+
84+
### 4. Supabase Database Setup
85+
86+
1. Create a new Supabase project
87+
2. Execute the SQL queries from `supabase-queries.md` in your Supabase SQL editor (You can also follow the tutorial video to setup the database)
88+
3. Set up the database triggers and functions
89+
4. Make sure to setup the right RLS policies (You can also follow the tutorial video to setup the RLS policies)
90+
91+
### 5. AI Model Links
92+
93+
Visit these links to set up your AI models:
94+
- [Flux Dev LORA model trainer](https://replicate.com/ostris/flux-dev-lora-trainer/train)
95+
- [Flux Dev Model](https://replicate.com/black-forest-labs/flux-dev)
96+
- [Flux Schnell Model](https://replicate.com/black-forest-labs/flux-schnell)
97+
98+
For stock images (not for training), I have used [Lummi AI](https://www.lummi.ai/)
99+
100+
### 6. Model Training Requirements
101+
102+
When training your custom model, ensure:
103+
- 10-15 images in total
104+
- Recommended breakdown for 12 images:
105+
- 6 face closeups
106+
- 3-4 half body closeups
107+
- 2-3 full body shots
108+
- No accessories on face/head
109+
- Different expressions, clothing, backgrounds
110+
- 1:1 resolution (1048x1048 or higher)
111+
- Images under 45MB total size
112+
113+
### 7. Stripe Setup
114+
115+
Watch our detailed video tutorial for Stripe integration setup: [Stripe Setup Tutorial](https://www.youtube.com/watch?v=7AQNeii5K7E&t=27960s)
116+
117+
### 8. Start Development Server
6118

7119
```bash
8120
npm run dev
9121
# or
10122
yarn dev
11123
# or
12124
pnpm dev
13-
# or
14-
bun dev
15125
```
16126

17-
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
127+
Visit `http://localhost:3000` to see your app.
128+
129+
## 📦 Project Structure
130+
131+
```
132+
├── app/ # Next.js 15 app directory
133+
├── components/ # React components
134+
├── lib/ # Utility, Supabase & Stripe functions
135+
├── public/ # Static assets
136+
└── globals.css # Global styles
137+
```
18138

19-
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
139+
## 💰 Pricing Plans
20140

21-
This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
141+
- **Hobby**: 1 trained model/month, 100 images/month
142+
- **Pro**: 2 trained models/month, 300 images/month
143+
- **Enterprise**: 5 trained models/month, unlimited images
22144

23-
## Learn More
145+
## 🎥 Tutorial Video
24146

25-
To learn more about Next.js, take a look at the following resources:
147+
For a complete setup walkthrough, check out our [video tutorial](https://youtu.be/7AQNeii5K7E).
26148

27-
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
28-
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
149+
## 🌟 Show Your Support
29150

30-
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
151+
Give a ⭐️ if this project helped you!
31152

32-
## Deploy on Vercel
153+
If you have any question or want a custom build for your business, you can reach out to me via:
33154

34-
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
155+
156+
- Twitter: https://twitter.com/code_bucks
157+
- Instagram: https://www.instagram.com/code.bucks/
35158

36-
Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
159+
MyChannel: https://www.youtube.com/codebucks
160+
My Website: https://devdreaming.com/

screenshots/Account-Settings.png

112 KB
Loading

screenshots/Authentication.png

795 KB
Loading

screenshots/Billing.png

144 KB
Loading

screenshots/Dashboard.png

678 KB
Loading

screenshots/Full Landing Page.png

2.52 MB
Loading

screenshots/Gallery.png

1.48 MB
Loading

screenshots/Image-Generation.png

575 KB
Loading

screenshots/Landing Page.png

1.59 MB
Loading

screenshots/Model-Training.png

157 KB
Loading

supabase-queries.md

+173
Original file line numberDiff line numberDiff line change
@@ -107,3 +107,176 @@ BEGIN
107107
RETURN NEW;
108108
END;
109109
```
110+
111+
## Decrease Credits Function Trigger
112+
113+
```sql
114+
CREATE TRIGGER decrease_credit
115+
AFTER INSERT ON public.generated_images
116+
FOR EACH ROW
117+
EXECUTE FUNCTION public.decrease_user_credit() SECURITY DEFINER;
118+
```
119+
120+
# You can find the following Stripe queries from sql quick start templates of supabase.
121+
122+
```sql
123+
/**
124+
* USERS
125+
* Note: This table contains user data. Users should only be able to view and update their own data.
126+
*/
127+
create table users (
128+
-- UUID from auth.users
129+
id uuid references auth.users not null primary key,
130+
full_name text,
131+
-- The customer's billing address, stored in JSON format.
132+
billing_address jsonb,
133+
-- Stores your customer's payment instruments.
134+
payment_method jsonb
135+
);
136+
alter table users
137+
enable row level security;
138+
create policy "Can view own user data." on users
139+
for select using ((select auth.uid()) = id);
140+
create policy "Can update own user data." on users
141+
for update using ((select auth.uid()) = id);
142+
143+
/**
144+
* This trigger automatically creates a user entry when a new user signs up via Supabase Auth.
145+
*/
146+
create function public.handle_new_user()
147+
returns trigger
148+
set search_path = ''
149+
as $$
150+
begin
151+
insert into public.users (id, full_name)
152+
values (new.id, new.raw_user_meta_data->>'full_name');
153+
return new;
154+
end;
155+
$$
156+
language plpgsql security definer;
157+
158+
create trigger on_auth_user_created
159+
after insert on auth.users
160+
for each row
161+
execute procedure public.handle_new_user();
162+
163+
/**
164+
* CUSTOMERS
165+
* Note: this is a private table that contains a mapping of user IDs to Stripe customer IDs.
166+
*/
167+
create table customers (
168+
-- UUID from auth.users
169+
id uuid references auth.users not null primary key,
170+
-- The user's customer ID in Stripe. User must not be able to update this.
171+
stripe_customer_id text
172+
);
173+
alter table customers enable row level security;
174+
-- No policies as this is a private table that the user must not have access to.
175+
176+
/**
177+
* PRODUCTS
178+
* Note: products are created and managed in Stripe and synced to our DB via Stripe webhooks.
179+
*/
180+
create table products (
181+
-- Product ID from Stripe, e.g. prod_1234.
182+
id text primary key,
183+
-- Whether the product is currently available for purchase.
184+
active boolean,
185+
-- The product's name, meant to be displayable to the customer. Whenever this product is sold via a subscription, name will show up on associated invoice line item descriptions.
186+
name text,
187+
-- The product's description, meant to be displayable to the customer. Use this field to optionally store a long form explanation of the product being sold for your own rendering purposes.
188+
description text,
189+
-- A URL of the product image in Stripe, meant to be displayable to the customer.
190+
image text,
191+
-- Set of key-value pairs, used to store additional information about the object in a structured format.
192+
metadata jsonb
193+
);
194+
alter table products
195+
enable row level security;
196+
create policy "Allow public read-only access." on products
197+
for select using (true);
198+
199+
/**
200+
* PRICES
201+
* Note: prices are created and managed in Stripe and synced to our DB via Stripe webhooks.
202+
*/
203+
create type pricing_type as enum ('one_time', 'recurring');
204+
create type pricing_plan_interval as enum ('day', 'week', 'month', 'year');
205+
create table prices (
206+
-- Price ID from Stripe, e.g. price_1234.
207+
id text primary key,
208+
-- The ID of the prduct that this price belongs to.
209+
product_id text references products,
210+
-- Whether the price can be used for new purchases.
211+
active boolean,
212+
-- A brief description of the price.
213+
description text,
214+
-- The unit amount as a positive integer in the smallest currency unit (e.g., 100 cents for US$1.00 or 100 for ¥100, a zero-decimal currency).
215+
unit_amount bigint,
216+
-- Three-letter ISO currency code, in lowercase.
217+
currency text check (char_length(currency) = 3),
218+
-- One of `one_time` or `recurring` depending on whether the price is for a one-time purchase or a recurring (subscription) purchase.
219+
type pricing_type,
220+
-- The frequency at which a subscription is billed. One of `day`, `week`, `month` or `year`.
221+
interval pricing_plan_interval,
222+
-- The number of intervals (specified in the `interval` attribute) between subscription billings. For example, `interval=month` and `interval_count=3` bills every 3 months.
223+
interval_count integer,
224+
-- Default number of trial days when subscribing a customer to this price using [`trial_from_plan=true`](https://stripe.com/docs/api#create_subscription-trial_from_plan).
225+
trial_period_days integer,
226+
-- Set of key-value pairs, used to store additional information about the object in a structured format.
227+
metadata jsonb
228+
);
229+
alter table prices
230+
enable row level security;
231+
create policy "Allow public read-only access." on prices
232+
for select using (true);
233+
234+
/**
235+
* SUBSCRIPTIONS
236+
* Note: subscriptions are created and managed in Stripe and synced to our DB via Stripe webhooks.
237+
*/
238+
create type subscription_status as enum ('trialing', 'active', 'canceled', 'incomplete', 'incomplete_expired', 'past_due', 'unpaid');
239+
create table subscriptions (
240+
-- Subscription ID from Stripe, e.g. sub_1234.
241+
id text primary key,
242+
user_id uuid references auth.users not null,
243+
-- The status of the subscription object, one of subscription_status type above.
244+
status subscription_status,
245+
-- Set of key-value pairs, used to store additional information about the object in a structured format.
246+
metadata jsonb,
247+
-- ID of the price that created this subscription.
248+
price_id text references prices,
249+
-- Quantity multiplied by the unit amount of the price creates the amount of the subscription. Can be used to charge multiple seats.
250+
quantity integer,
251+
-- If true the subscription has been canceled by the user and will be deleted at the end of the billing period.
252+
cancel_at_period_end boolean,
253+
-- Time at which the subscription was created.
254+
created timestamp with time zone default timezone('utc'::text, now()) not null,
255+
-- Start of the current period that the subscription has been invoiced for.
256+
current_period_start timestamp with time zone default timezone('utc'::text, now()) not null,
257+
-- End of the current period that the subscription has been invoiced for. At the end of this period, a new invoice will be created.
258+
current_period_end timestamp with time zone default timezone('utc'::text, now()) not null,
259+
-- If the subscription has ended, the timestamp of the date the subscription ended.
260+
ended_at timestamp with time zone default timezone('utc'::text, now()),
261+
-- A date in the future at which the subscription will automatically get canceled.
262+
cancel_at timestamp with time zone default timezone('utc'::text, now()),
263+
-- If the subscription has been canceled, the date of that cancellation. If the subscription was canceled with `cancel_at_period_end`, `canceled_at` will still reflect the date of the initial cancellation request, not the end of the subscription period when the subscription is automatically moved to a canceled state.
264+
canceled_at timestamp with time zone default timezone('utc'::text, now()),
265+
-- If the subscription has a trial, the beginning of that trial.
266+
trial_start timestamp with time zone default timezone('utc'::text, now()),
267+
-- If the subscription has a trial, the end of that trial.
268+
trial_end timestamp with time zone default timezone('utc'::text, now())
269+
);
270+
alter table subscriptions
271+
enable row level security;
272+
create policy "Can only view own subs data." on subscriptions
273+
for select using ((select auth.uid()) = user_id);
274+
275+
/**
276+
* REALTIME SUBSCRIPTIONS
277+
* Only allow realtime listening on public tables.
278+
*/
279+
drop publication if exists supabase_realtime;
280+
create publication supabase_realtime
281+
for table products, prices;
282+
```

0 commit comments

Comments
 (0)