Skip to content

Commit dc503a7

Browse files
Merge pull request #3 from Convert-ToInt32/feature/ecommerce-complete
Feature/ecommerce complete
2 parents 78831a8 + 88641b3 commit dc503a7

File tree

18 files changed

+217
-120
lines changed

18 files changed

+217
-120
lines changed

.github/workflows/deploy.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: Deploy to Vercel
2+
3+
on:
4+
push:
5+
branches: [ main, feature/ecommerce-complete ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
jobs:
10+
deploy:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v3
14+
15+
- name: Setup Node.js
16+
uses: actions/setup-node@v3
17+
with:
18+
node-version: '18'
19+
cache: 'npm'
20+
21+
- name: Install dependencies
22+
run: npm ci
23+
24+
- name: Build application
25+
run: npm run build
26+
27+
- name: Deploy to Vercel
28+
uses: amondnet/vercel-action@v25
29+
with:
30+
vercel-token: ${{ secrets.VERCEL_TOKEN }}
31+
vercel-org-id: ${{ secrets.ORG_ID }}
32+
vercel-project-id: ${{ secrets.PROJECT_ID }}
33+
vercel-args: '--prod'

env.example

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Database
2+
DATABASE_URL="postgresql://username:password@localhost:5432/cartzy"
3+
4+
# NextAuth
5+
NEXTAUTH_URL="http://localhost:3001"
6+
NEXTAUTH_SECRET="your-secret-key-here"
7+
8+
# OAuth Providers
9+
GOOGLE_CLIENT_ID="your-google-client-id"
10+
GOOGLE_CLIENT_SECRET="your-google-client-secret"
11+
GITHUB_CLIENT_ID="your-github-client-id"
12+
GITHUB_CLIENT_SECRET="your-github-client-secret"

eslint.config.mjs

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,25 @@
1-
import { dirname } from "path";
2-
import { fileURLToPath } from "url";
3-
import { FlatCompat } from "@eslint/eslintrc";
1+
import js from '@eslint/js'
2+
import { FlatCompat } from '@eslint/eslintrc'
3+
import path from 'path'
4+
import { fileURLToPath } from 'url'
45

5-
const __filename = fileURLToPath(import.meta.url);
6-
const __dirname = dirname(__filename);
6+
const __filename = fileURLToPath(import.meta.url)
7+
const __dirname = path.dirname(__filename)
78

89
const compat = new FlatCompat({
910
baseDirectory: __dirname,
10-
});
11+
})
1112

1213
const eslintConfig = [
13-
...compat.extends("next/core-web-vitals", "next/typescript"),
14-
];
14+
js.configs.recommended,
15+
...compat.extends('next/core-web-vitals'),
16+
{
17+
rules: {
18+
'react-hooks/exhaustive-deps': 'warn',
19+
'no-undef': 'off',
20+
'no-unused-vars': 'warn',
21+
},
22+
},
23+
]
1524

16-
export default eslintConfig;
25+
export default eslintConfig

next.config.ts

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,10 @@ import type { NextConfig } from "next";
22

33
const nextConfig: NextConfig = {
44
images: {
5-
remotePatterns: [
6-
{
7-
protocol: "https",
8-
hostname: "lh3.googleusercontent.com",
9-
},
10-
{
11-
protocol: "https",
12-
hostname: "avatars.githubusercontent.com",
13-
},
14-
{
15-
protocol: "https",
16-
hostname: "images.unsplash.com",
17-
},
18-
],
5+
domains: ['images.unsplash.com'],
196
},
7+
serverExternalPackages: ['@prisma/client'],
8+
output: 'standalone',
209
};
2110

2211
export default nextConfig;

package.json

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,15 @@
33
"version": "0.1.0",
44
"private": true,
55
"scripts": {
6-
"dev": "next dev --turbopack",
6+
"dev": "next dev -p 3001",
77
"build": "next build",
8-
"start": "next start",
8+
"start": "bash start.sh",
99
"lint": "next lint",
10-
"db:seed": "tsx prisma/seed.ts"
10+
"db:generate": "prisma generate",
11+
"db:push": "prisma db push",
12+
"db:migrate": "prisma migrate deploy",
13+
"db:seed": "tsx prisma/seed.ts",
14+
"postinstall": "prisma generate"
1115
},
1216
"dependencies": {
1317
"@auth/prisma-adapter": "^2.10.0",

railway-env.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Railway Environment Variables Setup
2+
3+
## Required Environment Variables for Railway:
4+
5+
### Database (Auto-configured by Railway)
6+
- `DATABASE_URL` - Automatically set by Railway PostgreSQL service
7+
8+
### NextAuth Configuration
9+
- `NEXTAUTH_URL` - Your Railway app URL (e.g., https://your-app.railway.app)
10+
- `NEXTAUTH_SECRET` - Generate with: `openssl rand -base64 32`
11+
12+
### OAuth Providers (Optional for now)
13+
- `GOOGLE_CLIENT_ID` - Your Google OAuth client ID
14+
- `GOOGLE_CLIENT_SECRET` - Your Google OAuth client secret
15+
- `GITHUB_CLIENT_ID` - Your GitHub OAuth client ID
16+
- `GITHUB_CLIENT_SECRET` - Your GitHub OAuth client secret
17+
18+
## Setup Steps:
19+
20+
1. **In Railway Dashboard:**
21+
- Go to your project
22+
- Click on your app service
23+
- Go to "Variables" tab
24+
- Add the environment variables above
25+
26+
2. **Generate NEXTAUTH_SECRET:**
27+
```bash
28+
openssl rand -base64 32
29+
```
30+
31+
3. **Set NEXTAUTH_URL:**
32+
- Use your Railway app URL
33+
- Format: https://your-app-name.railway.app
34+
35+
## Database Connection:
36+
- Railway automatically provides `DATABASE_URL`
37+
- No additional setup needed for database

railway.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[build]
2+
builder = "nixpacks"
3+
4+
[deploy]
5+
startCommand = "npm start"
6+
healthcheckPath = "/"
7+
healthcheckTimeout = 300
8+
restartPolicyType = "on_failure"
9+
restartPolicyMaxRetries = 10

src/app/api/cart/route.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
import { NextRequest, NextResponse } from "next/server"
2-
import { getServerSession } from "next-auth"
3-
import { authOptions } from "@/lib/auth"
2+
import { auth } from "@/lib/auth"
43
import { prisma } from "@/lib/prisma"
54

65
export async function GET() {
76
try {
8-
const session = await getServerSession(authOptions)
7+
const session = await auth()
98

109
if (!session?.user?.email) {
1110
return NextResponse.json({ error: "Unauthorized" }, { status: 401 })
@@ -44,7 +43,7 @@ export async function GET() {
4443

4544
export async function POST(request: NextRequest) {
4645
try {
47-
const session = await getServerSession(authOptions)
46+
const session = await auth()
4847

4948
if (!session?.user?.email) {
5049
return NextResponse.json({ error: "Unauthorized" }, { status: 401 })
@@ -68,7 +67,7 @@ export async function POST(request: NextRequest) {
6867
// Add new cart items
6968
if (items.length > 0) {
7069
await prisma.cartItem.createMany({
71-
data: items.map((item: any) => ({
70+
data: items.map((item: { productId: string; quantity: number }) => ({
7271
userId: user.id,
7372
productId: item.productId,
7473
quantity: item.quantity

src/app/layout.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import React from "react"
12
import type { Metadata } from "next";
23
import { Geist, Geist_Mono } from "next/font/google";
34
import "./globals.css";

src/app/products/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { Notification } from "@/components/Notification";
77
import { SearchBar } from "@/components/SearchBar";
88
import { FeaturedCarousel } from "@/components/FeaturedCarousel";
99
import Image from "next/image";
10-
import { LoadingSpinner, ProductCardSkeleton, CategorySkeleton } from "@/components/LoadingSpinner";
10+
import { ProductCardSkeleton, CategorySkeleton } from "@/components/LoadingSpinner";
1111
import { useEffect, useState } from "react";
1212

1313
interface Product {

0 commit comments

Comments
 (0)