-
Notifications
You must be signed in to change notification settings - Fork 0
Add e-commerce starter (React frontend + Spring Boot backend) #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| node_modules/ | ||
| frontend/dist/ | ||
| backend/target/ | ||
| .env |
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,33 @@ | ||||||||||
| # E-Commerce Application | ||||||||||
|
|
||||||||||
| This repository contains a simple e-commerce application with a React frontend, a Spring Boot backend, and a MySQL database configuration. | ||||||||||
|
|
||||||||||
| ## Frontend (React) | ||||||||||
|
|
||||||||||
| ```bash | ||||||||||
| cd frontend | ||||||||||
| npm install | ||||||||||
| npm run dev | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| The frontend expects the backend to run on `http://localhost:8080` and proxies `/api` requests via Vite. | ||||||||||
|
|
||||||||||
| ## Backend (Spring Boot) | ||||||||||
|
|
||||||||||
| ```bash | ||||||||||
| cd backend | ||||||||||
| ./mvnw spring-boot:run | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| Update the MySQL credentials in `backend/src/main/resources/application.properties` before running the backend. | ||||||||||
|
|
||||||||||
| ## Database (MySQL) | ||||||||||
|
|
||||||||||
| Example database setup: | ||||||||||
|
|
||||||||||
| ```sql | ||||||||||
| CREATE DATABASE ecom_db; | ||||||||||
| CREATE USER 'ecom_user'@'localhost' IDENTIFIED BY 'change_me'; | ||||||||||
| GRANT ALL PRIVILEGES ON ecom_db.* TO 'ecom_user'@'localhost'; | ||||||||||
|
Comment on lines
+30
to
+31
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Tighten DB privileges in the setup example. 🔒 Suggested SQL example-GRANT ALL PRIVILEGES ON ecom_db.* TO 'ecom_user'@'localhost';
+GRANT SELECT, INSERT, UPDATE, DELETE ON ecom_db.* TO 'ecom_user'@'localhost';📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||
| FLUSH PRIVILEGES; | ||||||||||
| ``` | ||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
| <modelVersion>4.0.0</modelVersion> | ||
|
|
||
| <parent> | ||
| <groupId>org.springframework.boot</groupId> | ||
| <artifactId>spring-boot-starter-parent</artifactId> | ||
| <version>3.2.3</version> | ||
| <relativePath/> | ||
| </parent> | ||
|
|
||
| <groupId>com.example</groupId> | ||
| <artifactId>ecom-backend</artifactId> | ||
| <version>0.0.1-SNAPSHOT</version> | ||
| <name>ecom-backend</name> | ||
| <description>E-commerce API with Spring Boot</description> | ||
|
|
||
| <properties> | ||
| <java.version>17</java.version> | ||
| </properties> | ||
|
|
||
| <dependencies> | ||
| <dependency> | ||
| <groupId>org.springframework.boot</groupId> | ||
| <artifactId>spring-boot-starter-web</artifactId> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>org.springframework.boot</groupId> | ||
| <artifactId>spring-boot-starter-data-jpa</artifactId> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>com.mysql</groupId> | ||
| <artifactId>mysql-connector-j</artifactId> | ||
| <scope>runtime</scope> | ||
| </dependency> | ||
| </dependencies> | ||
|
|
||
| <build> | ||
| <plugins> | ||
| <plugin> | ||
| <groupId>org.springframework.boot</groupId> | ||
| <artifactId>spring-boot-maven-plugin</artifactId> | ||
| </plugin> | ||
| </plugins> | ||
| </build> | ||
| </project> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| package com.example.ecom; | ||
|
|
||
| import org.springframework.boot.SpringApplication; | ||
| import org.springframework.boot.autoconfigure.SpringBootApplication; | ||
|
|
||
| @SpringBootApplication | ||
| public class EcomApplication { | ||
|
|
||
| public static void main(String[] args) { | ||
| SpringApplication.run(EcomApplication.class, args); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,3 @@ | ||||||||||
| package com.example.ecom; | ||||||||||
|
|
||||||||||
| public record Product(Long id, String name, String description, double price) {} | ||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: # First, locate the Product.java file and examine its current state
find . -name "Product.java" -type f | head -20Repository: ramcharan032785-code/Codex Length of output: 123 🏁 Script executed: # Search for all Product constructor instantiations
rg -nP --type=java '\bnew\s+Product\s*\(' -B2 -A2Repository: ramcharan032785-code/Codex Length of output: 910 🏁 Script executed: # Check for any Product-related tests or serialization configs
rg -nP --type=java 'Product.*price|price.*Product' -B1 -A1 | head -50Repository: ramcharan032785-code/Codex Length of output: 259 🏁 Script executed: # Look for any BigDecimal usage patterns already in the codebase
rg -nP --type=java 'BigDecimal' | head -20Repository: ramcharan032785-code/Codex Length of output: 52 🏁 Script executed: # Look for Product tests
find . -name "*ProductTest*" -o -name "*Test*Product*" | grep -i testRepository: ramcharan032785-code/Codex Length of output: 52 🏁 Script executed: # Check if Product is a JPA entity or just a record
cat -n ./backend/src/main/java/com/example/ecom/Product.javaRepository: ramcharan032785-code/Codex Length of output: 198 🏁 Script executed: # Check for any price-related operations or calculations in the codebase
rg -nP --type=java '\bprice\b' -B1 -A1 | head -60Repository: ramcharan032785-code/Codex Length of output: 259 Use The e-commerce domain requires precise monetary handling. Using Three call sites in Proposed fix+import java.math.BigDecimal;
-
-public record Product(Long id, String name, String description, double price) {}
+public record Product(Long id, String name, String description, BigDecimal price) {}Update call sites in -new Product(1L, "Lunar Running Shoes", "Lightweight sneakers with responsive cushioning.", 129.00)
+new Product(1L, "Lunar Running Shoes", "Lightweight sneakers with responsive cushioning.", new BigDecimal("129.00"))📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| package com.example.ecom; | ||
|
|
||
| import java.util.List; | ||
| import org.springframework.web.bind.annotation.GetMapping; | ||
| import org.springframework.web.bind.annotation.RequestMapping; | ||
| import org.springframework.web.bind.annotation.RestController; | ||
|
|
||
| @RestController | ||
| @RequestMapping("/api/products") | ||
| public class ProductController { | ||
|
|
||
| @GetMapping | ||
| public List<Product> getProducts() { | ||
| return List.of( | ||
| new Product(1L, "Lunar Running Shoes", "Lightweight sneakers with responsive cushioning.", 129.00), | ||
| new Product(2L, "Aurora Smartwatch", "Track workouts, sleep, and notifications in style.", 249.00), | ||
| new Product(3L, "Nebula Backpack", "Weather-resistant backpack with laptop sleeve.", 89.00) | ||
| ); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,9 @@ | ||||||||||||||||||
| server.port=8080 | ||||||||||||||||||
|
|
||||||||||||||||||
| spring.datasource.url=jdbc:mysql://localhost:3306/ecom_db | ||||||||||||||||||
| spring.datasource.username=ecom_user | ||||||||||||||||||
| spring.datasource.password=change_me | ||||||||||||||||||
| spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver | ||||||||||||||||||
|
Comment on lines
+3
to
+6
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do not commit live datasource credentials in shared config. 🔐 Suggested change-spring.datasource.url=jdbc:mysql://localhost:3306/ecom_db
-spring.datasource.username=ecom_user
-spring.datasource.password=change_me
+spring.datasource.url=${DB_URL:jdbc:mysql://localhost:3306/ecom_db}
+spring.datasource.username=${DB_USERNAME:ecom_user}
+spring.datasource.password=${DB_PASSWORD}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||
|
|
||||||||||||||||||
| spring.jpa.hibernate.ddl-auto=update | ||||||||||||||||||
| spring.jpa.show-sql=true | ||||||||||||||||||
|
Comment on lines
+8
to
+9
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid schema mutation and SQL logging as shared defaults. 🛠️ Suggested change-spring.jpa.hibernate.ddl-auto=update
-spring.jpa.show-sql=true
+spring.jpa.hibernate.ddl-auto=validate
+spring.jpa.show-sql=falseUse a dedicated 🤖 Prompt for AI Agents |
||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| <!doctype html> | ||
| <html lang="en"> | ||
| <head> | ||
| <meta charset="UTF-8" /> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
| <title>NovaCart</title> | ||
| </head> | ||
| <body> | ||
| <div id="root"></div> | ||
| <script type="module" src="/src/main.jsx"></script> | ||
| </body> | ||
| </html> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| { | ||
| "name": "ecom-frontend", | ||
| "private": true, | ||
| "version": "0.1.0", | ||
| "type": "module", | ||
| "scripts": { | ||
| "dev": "vite", | ||
| "build": "vite build", | ||
| "preview": "vite preview" | ||
| }, | ||
| "dependencies": { | ||
| "react": "^18.2.0", | ||
| "react-dom": "^18.2.0" | ||
| }, | ||
| "devDependencies": { | ||
| "@vitejs/plugin-react": "^4.2.0", | ||
| "vite": "^5.0.0" | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,111 @@ | ||
| import { useEffect, useState } from 'react'; | ||
|
|
||
| const fallbackProducts = [ | ||
| { | ||
| id: 1, | ||
| name: 'Lunar Running Shoes', | ||
| price: 129.0, | ||
| description: 'Lightweight sneakers with responsive cushioning.' | ||
| }, | ||
| { | ||
| id: 2, | ||
| name: 'Aurora Smartwatch', | ||
| price: 249.0, | ||
| description: 'Track workouts, sleep, and notifications in style.' | ||
| }, | ||
| { | ||
| id: 3, | ||
| name: 'Nebula Backpack', | ||
| price: 89.0, | ||
| description: 'Weather-resistant backpack with laptop sleeve.' | ||
| } | ||
| ]; | ||
|
|
||
| export default function App() { | ||
| const [products, setProducts] = useState([]); | ||
| const [status, setStatus] = useState('Loading products...'); | ||
|
|
||
| useEffect(() => { | ||
| const loadProducts = async () => { | ||
| try { | ||
| const response = await fetch('/api/products'); | ||
| if (!response.ok) { | ||
| throw new Error('Failed to load products'); | ||
| } | ||
| const data = await response.json(); | ||
| setProducts(data); | ||
| setStatus(''); | ||
| } catch (error) { | ||
| setProducts(fallbackProducts); | ||
| setStatus('Showing demo products. Connect the Spring Boot API for live data.'); | ||
| } | ||
| }; | ||
|
|
||
| loadProducts(); | ||
| }, []); | ||
|
|
||
| return ( | ||
| <div className="page"> | ||
| <header className="hero"> | ||
| <div> | ||
| <p className="eyebrow">NovaCart</p> | ||
| <h1>Space-grade gear for everyday adventures.</h1> | ||
| <p className="subtitle"> | ||
| Explore curated essentials across tech, travel, and lifestyle. Fast delivery, | ||
| flexible returns, and a seamless checkout experience. | ||
| </p> | ||
| <div className="cta-row"> | ||
| <button className="primary">Shop new arrivals</button> | ||
| <button className="ghost">View categories</button> | ||
| </div> | ||
| </div> | ||
| <div className="hero-card"> | ||
| <h2>Weekly spotlight</h2> | ||
| <p>Save 15% on bundles with code ORBIT.</p> | ||
| <ul> | ||
| <li>Free shipping over $75</li> | ||
| <li>2-year warranty included</li> | ||
| <li>24/7 concierge support</li> | ||
| </ul> | ||
| </div> | ||
| </header> | ||
|
|
||
| <section className="section"> | ||
| <div className="section-header"> | ||
| <h2>Featured products</h2> | ||
| {status ? <span className="status">{status}</span> : null} | ||
| </div> | ||
| <div className="grid"> | ||
| {products.map((product) => ( | ||
| <article className="card" key={product.id}> | ||
| <div className="card-top"> | ||
| <span className="badge">New</span> | ||
| <h3>{product.name}</h3> | ||
| <p>{product.description}</p> | ||
| </div> | ||
| <div className="card-bottom"> | ||
| <span className="price">${product.price.toFixed(2)}</span> | ||
| <button>Add to cart</button> | ||
| </div> | ||
| </article> | ||
| ))} | ||
| </div> | ||
| </section> | ||
|
|
||
| <section className="section dark"> | ||
| <div> | ||
| <h2>Fast checkout, flexible payments.</h2> | ||
| <p> | ||
| Connect with Apple Pay, PayPal, or card-on-file. Keep your favorites in one | ||
| place and reorder in seconds. | ||
| </p> | ||
| </div> | ||
| <div className="pill-row"> | ||
| <span>1-click reorder</span> | ||
| <span>Live order tracking</span> | ||
| <span>Instant support</span> | ||
| </div> | ||
| </section> | ||
| </div> | ||
| ); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| import React from 'react'; | ||
| import ReactDOM from 'react-dom/client'; | ||
| import App from './App.jsx'; | ||
| import './styles.css'; | ||
|
|
||
| ReactDOM.createRoot(document.getElementById('root')).render( | ||
| <React.StrictMode> | ||
| <App /> | ||
| </React.StrictMode> | ||
| ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: ramcharan032785-code/Codex
Length of output: 107
Either commit Maven Wrapper scripts or update the backend setup command in the documentation.
The referenced
./mvnwcommand in Line 19 does not exist in the repository. New contributors following these instructions will encounter a "command not found" error. Either commit the Maven Wrapper scripts to the repository or provide an alternative command (e.g.,mvn spring-boot:runif Maven is available globally).🤖 Prompt for AI Agents