Spring Boot project specifictions (2 wheeler service)
Two‑Wheeler Service Worksheet Application
Full‑Stack Guide: Spring Boot +
MySQL + React + Tailwind
1.
Backend – Spring Boot + MySQL
1.1
Entities
Customer.java
import
jakarta.persistence.*;
@Entity
@Table(name
= "customer")
public
class Customer {
@Id
@GeneratedValue(strategy =
GenerationType.IDENTITY)
private Long id;
private String name;
private String phone;
private String email;
// getters and setters
}
Vehicle.java
import
jakarta.persistence.*;
@Entity
@Table(name
= "vehicle")
public
class Vehicle {
@Id
@GeneratedValue(strategy =
GenerationType.IDENTITY)
private Long id;
private String regNumber;
private String brand;
private String model;
@ManyToOne
@JoinColumn(name = "customer_id")
private Customer customer;
// getters and setters
}
ServiceWorksheet.java
import
jakarta.persistence.*;
import
java.time.LocalDate;
@Entity
@Table(name
= "service_worksheet")
public
class ServiceWorksheet {
@Id
@GeneratedValue(strategy =
GenerationType.IDENTITY)
private Long id;
@ManyToOne
@JoinColumn(name = "vehicle_id")
private Vehicle vehicle;
private LocalDate serviceDate;
private String issuesReported;
private String workDone;
private String partsReplaced;
private Double cost;
// getters and setters
}
1.2
Repository Layer
public
interface CustomerRepository extends JpaRepository<Customer, Long> {}
public
interface VehicleRepository extends JpaRepository<Vehicle, Long> {}
public
interface ServiceWorksheetRepository extends JpaRepository<ServiceWorksheet,
Long> {}
1.3
Service Layer
@Service
public
class WorksheetService {
@Autowired private ServiceWorksheetRepository repo;
public ServiceWorksheet
createWorksheet(ServiceWorksheet ws) {
return repo.save(ws);
}
public List<ServiceWorksheet>
getAllWorksheets() {
return repo.findAll();
}
}
1.4
Controller Layer
@RestController
@RequestMapping("/api/worksheets")
public
class WorksheetController {
@Autowired private WorksheetService
service;
@PostMapping
public ServiceWorksheet
addWorksheet(@RequestBody ServiceWorksheet ws) {
return service.createWorksheet(ws);
}
@GetMapping
public List<ServiceWorksheet>
getWorksheets() {
return service.getAllWorksheets();
}
}
2.
Database Configuration
application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/two_wheeler_service
spring.datasource.username=root
spring.datasource.password=yourpassword
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
spring.jpa.properties.hibernate.format_sql=true
🔑
Key Point
- spring.jpa.hibernate.ddl-auto=update + @Entity annotations = automatic table creation.
- You must manually create the database schema once:
·
CREATE DATABASE two_wheeler_service;
3.
Sample Data Seeding
Option
A: data.sql
INSERT
INTO customer (name, phone, email) VALUES ('Ravi Kumar', '9876543210',
'ravi@example.com');
INSERT
INTO customer (name, phone, email) VALUES ('Priya Sharma', '9123456780',
'priya@example.com');
INSERT
INTO vehicle (reg_number, brand, model, customer_id) VALUES ('TN09AB1234',
'Honda', 'Activa', 1);
INSERT
INTO vehicle (reg_number, brand, model, customer_id) VALUES ('TN10XY5678',
'Yamaha', 'FZ', 2);
INSERT
INTO service_worksheet (vehicle_id, service_date, issues_reported, work_done,
parts_replaced, cost)
VALUES
(1, '2026-06-28', 'Brake noise', 'Brake pad replaced', 'Brake pads', 1200.00);
Option
B: CommandLineRunner
@Bean
CommandLineRunner
initData(CustomerRepository customerRepo, VehicleRepository vehicleRepo,
ServiceWorksheetRepository wsRepo) {
return args -> {
Customer c1 = customerRepo.save(new
Customer(null, "Ravi Kumar", "9876543210",
"ravi@example.com"));
Vehicle v1 = vehicleRepo.save(new
Vehicle(null, "TN09AB1234", "Honda", "Activa",
c1));
wsRepo.save(new ServiceWorksheet(null,
v1, LocalDate.now(), "Brake noise", "Brake pad replaced",
"Brake pads", 1200.0));
};
}
4.
Frontend – React + Tailwind
4.1
Setup
npm
create vite@latest service-worksheet-ui --template react
cd
service-worksheet-ui
npm
install axios tailwindcss @tailwindcss/vite
vite.config.js
import
{ defineConfig } from 'vite'
import
react from '@vitejs/plugin-react'
import
tailwindcss from '@tailwindcss/vite'
export
default defineConfig({
plugins: [react(), tailwindcss()],
})
index.css
@import
"tailwindcss";
4.2
Components
WorksheetForm.jsx
import
{ useState } from "react";
import
axios from "axios";
export
default function WorksheetForm({ onAdded }) {
const [form, setForm] = useState({
vehicleId:"", issuesReported:"", workDone:"",
partsReplaced:"", cost:"" });
const handleSubmit = async (e) => {
e.preventDefault();
await
axios.post("http://localhost:8080/api/worksheets", form);
onAdded();
};
return (
<form onSubmit={handleSubmit}
className="p-4 bg-white shadow rounded space-y-3">
<input className="border p-2
w-full" placeholder="Vehicle ID"
onChange={e=>setForm({...form,
vehicleId:e.target.value})}/>
<textarea className="border p-2
w-full" placeholder="Issues Reported"
onChange={e=>setForm({...form,
issuesReported:e.target.value})}/>
<textarea className="border p-2
w-full" placeholder="Work Done"
onChange={e=>setForm({...form,
workDone:e.target.value})}/>
<input className="border p-2
w-full" placeholder="Parts Replaced"
onChange={e=>setForm({...form,
partsReplaced:e.target.value})}/>
<input className="border p-2
w-full" placeholder="Cost"
onChange={e=>setForm({...form,
cost:e.target.value})}/>
<button className="bg-blue-500
text-white px-4 py-2 rounded">Save</button>
</form>
);
}
WorksheetList.jsx
import
{ useEffect, useState } from "react";
import
axios from "axios";
export
default function WorksheetList() {
const [worksheets, setWorksheets] =
useState([]);
useEffect(() => {
axios.get("http://localhost:8080/api/worksheets")
.then(res =>
setWorksheets(res.data));
}, []);
return (
<table className="table-auto w-full
border-collapse border">
<thead>
<tr
className="bg-gray-200">
<th className="border
px-2">Vehicle ID</th>
<th className="border
px-2">Issues</th>
<th className="border
px-2">Work Done</th>
<th className="border
px-2">Parts</th>
<th className="border
px-2">Cost</th>
</tr>
</thead>
<tbody>
{worksheets.map(ws => (
<tr key={ws.id}>
<td className="border
px-2">{ws.vehicle.id}</td>
<td className="border
px-2">{ws.issuesReported}</td>
<td className="border
px-2">{ws.workDone}</td>
<td className="border
px-2">{ws.partsReplaced}</td>
<td className="border
px-2">{ws.cost}</td>
</tr>
))}
</tbody>
</table>
);
}
5.
Integration
- Backend: http://localhost:8080
- Frontend: http://localhost:5173
- Enable CORS in Spring Boot:
@CrossOrigin(origins="http://localhost:5173")
6.
Next Steps
- Add authentication (Spring Security + JWT).
- Expand worksheet with status (Pending, Completed).
- Generate PDF invoice from worksheet.
- Add search/filter for vehicles and customers.
Comments
Post a Comment