From 4dc0b37bada7e0d94f6fdf64f1e4a46f5124e73b Mon Sep 17 00:00:00 2001 From: Sidharth Prabhu Date: Thu, 9 Apr 2026 15:35:42 +0530 Subject: [PATCH] Vendor Dashboard and Store dashboard added --- backend/mvnw | 0 .../sales/service/SystemUserService.java | 23 +++++++++----- .../src/main/resources/application.properties | 8 +++-- frontend/src/components/Sidebar.tsx | 6 ++-- frontend/src/pages/Dashboard.tsx | 30 +++++++++---------- frontend/src/pages/Login.tsx | 4 +-- frontend/src/pages/PurchaseAnalytics.tsx | 16 +++++----- frontend/src/pages/PurchaseSummary.tsx | 12 ++++---- frontend/src/pages/StoreDashboard.tsx | 26 ++++++++-------- 9 files changed, 68 insertions(+), 57 deletions(-) mode change 100644 => 100755 backend/mvnw diff --git a/backend/mvnw b/backend/mvnw old mode 100644 new mode 100755 diff --git a/backend/src/main/java/com/rit/canteen/sales/service/SystemUserService.java b/backend/src/main/java/com/rit/canteen/sales/service/SystemUserService.java index a68d2eaa..84fcf996 100644 --- a/backend/src/main/java/com/rit/canteen/sales/service/SystemUserService.java +++ b/backend/src/main/java/com/rit/canteen/sales/service/SystemUserService.java @@ -4,6 +4,7 @@ import com.rit.canteen.sales.model.SystemUser; import com.rit.canteen.sales.repository.SystemUserRepository; import jakarta.annotation.PostConstruct; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.stereotype.Service; @@ -19,6 +20,12 @@ public class SystemUserService { @Autowired private BCryptPasswordEncoder passwordEncoder; + @Value("${app.master.username:admin}") + private String masterUsername; + + @Value("${app.master.password:admin}") + private String masterPassword; + @PostConstruct public void init() { // Handle migration from old credentials if they exist @@ -28,31 +35,31 @@ public class SystemUserService { repository.delete(oldUser); System.out.println(">>> REMOVED OBSOLETE MASTER USER: admin@ritcanteen.com"); } else { - oldUser.setEmail("admin"); - oldUser.setPassword(passwordEncoder.encode("admin")); + oldUser.setEmail(masterUsername); + oldUser.setPassword(passwordEncoder.encode(masterPassword)); repository.save(oldUser); System.out.println(">>> MIGRATED MASTER USER: admin / admin"); } }); // Ensure 'admin' user exists and has the correct password - Optional adminUser = repository.findByEmail("admin"); + Optional adminUser = repository.findByEmail(masterUsername); if (adminUser.isPresent()) { SystemUser admin = adminUser.get(); - admin.setPassword(passwordEncoder.encode("admin")); + admin.setPassword(passwordEncoder.encode(masterPassword)); admin.setRole("MASTER"); repository.save(admin); - System.out.println(">>> UPDATED MASTER USER PASSWORD: admin / admin"); + System.out.println(">>> UPDATED MASTER USER PASSWORD: " + masterUsername + " / " + masterPassword); } else { SystemUser master = new SystemUser(); master.setName("Admin Master"); - master.setEmail("admin"); - master.setPassword(passwordEncoder.encode("admin")); + master.setEmail(masterUsername); + master.setPassword(passwordEncoder.encode(masterPassword)); master.setRole("MASTER"); master.setPermissions(List.of("dashboard", "sale", "customers", "purchases", "inventory", "expense", "reports", "stores", "table", "wallet", "promotions", "feedback")); master.setViewOnly(false); repository.save(master); - System.out.println(">>> SEEDED MASTER USER: admin / admin"); + System.out.println(">>> SEEDED MASTER USER: " + masterUsername + " / " + masterPassword); } } diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties index 0b4598ba..9dabc2ea 100644 --- a/backend/src/main/resources/application.properties +++ b/backend/src/main/resources/application.properties @@ -1,11 +1,15 @@ spring.application.name=backend server.address=0.0.0.0 -spring.datasource.url=jdbc:postgresql://localhost:5432/canteen_automation +spring.datasource.url=jdbc:postgresql://localhost:5432/positeasy spring.datasource.username=postgres -spring.datasource.password=Abiram@07 +spring.datasource.password=sidharth spring.datasource.driver-class-name=org.postgresql.Driver spring.jpa.hibernate.ddl-auto=update spring.jpa.show-sql=true spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect + +# Master Account Credentials +app.master.username=admin +app.master.password=admin diff --git a/frontend/src/components/Sidebar.tsx b/frontend/src/components/Sidebar.tsx index a8b8b459..978ccf8b 100644 --- a/frontend/src/components/Sidebar.tsx +++ b/frontend/src/components/Sidebar.tsx @@ -198,7 +198,7 @@ const Sidebar = () => { className={cn( "w-full flex items-center justify-between p-2.5 rounded-xl text-sm font-semibold transition-all duration-200 group", openMenus.includes(item.title) - ? "text-[#521c4b] bg-[#521c4b]/5" + ? "text-[#0f4475] bg-[#0f4475]/5" : "text-[#475569] hover:bg-gray-50 hover:text-[#1e293b]" )} > @@ -234,7 +234,7 @@ const Sidebar = () => { className={({ isActive }) => cn( "flex items-center gap-3 py-2 px-4 rounded-lg text-[13px] font-medium transition-all group relative", isActive - ? "text-white bg-[#521c4b] shadow-md shadow-[#521c4b]/10" + ? "text-white bg-[#0f4475] shadow-md shadow-[#0f4475]/10" : "text-[#64748b] hover:text-[#1e293b] hover:translate-x-1" )} > @@ -267,7 +267,7 @@ const Sidebar = () => { className={({ isActive }) => cn( "flex items-center gap-3 p-2.5 rounded-xl text-sm font-semibold transition-all duration-200 group", isActive - ? "bg-[#521c4b] text-white shadow-lg shadow-[#521c4b]/15" + ? "bg-[#0f4475] text-white shadow-lg shadow-[#0f4475]/15" : "text-[#475569] hover:bg-gray-50 hover:text-[#1e293b]" )} > diff --git a/frontend/src/pages/Dashboard.tsx b/frontend/src/pages/Dashboard.tsx index e6b738ae..323f5ec2 100644 --- a/frontend/src/pages/Dashboard.tsx +++ b/frontend/src/pages/Dashboard.tsx @@ -50,7 +50,7 @@ const Dashboard = () => { Loading Business Intelligence... @@ -74,7 +74,7 @@ const Dashboard = () => { -

Dashboard

+

Dashboard

Good morning

@@ -85,7 +85,7 @@ const Dashboard = () => {

-
@@ -105,11 +105,11 @@ const Dashboard = () => { key={tab} title={`View ${tab} analysis and trends`} onClick={() => setActiveTab(tab)} - className={`pb-4 text-[11px] font-black uppercase tracking-widest transition-all relative ${activeTab === tab ? 'text-[#521c4b]' : 'text-slate-400 hover:text-slate-600'}`} + className={`pb-4 text-[11px] font-black uppercase tracking-widest transition-all relative ${activeTab === tab ? 'text-[#0f4475]' : 'text-slate-400 hover:text-slate-600'}`} > {tab} {activeTab === tab && ( - + )} ))} @@ -117,7 +117,7 @@ const Dashboard = () => {
-
+
Today's Revenue
@@ -194,7 +194,7 @@ const Dashboard = () => { key={range} title={`Analyze data from ${range.toLowerCase()}`} onClick={() => setTimeRange(range)} - className={`whitespace-nowrap px-3 py-2 text-[10px] font-black uppercase tracking-widest transition-all rounded-xl ${timeRange === range ? 'text-white bg-[#521c4b] shadow-md shadow-[#521c4b]/20' : 'text-slate-400 hover:text-slate-600'}`} + className={`whitespace-nowrap px-3 py-2 text-[10px] font-black uppercase tracking-widest transition-all rounded-xl ${timeRange === range ? 'text-white bg-[#0f4475] shadow-md shadow-[#0f4475]/20' : 'text-slate-400 hover:text-slate-600'}`} > {range} @@ -202,7 +202,7 @@ const Dashboard = () => {
{/* Total Orders Card */} -
+
@@ -216,9 +216,9 @@ const Dashboard = () => {
{/* Expenses Card */} -
+
-
+

Total Expenses

@@ -249,7 +249,7 @@ const Dashboard = () => { ))}
-
@@ -259,15 +259,15 @@ const Dashboard = () => {

Store Performance

- +
{(storeOverview.length > 0 ? storeOverview : [{name: 'No active sales currently', sale: 0, orders: 0, taxes: 0, purchase: 0}]).map((store: any, idx: number) => ( -
+

{store.name} - +

@@ -292,7 +292,7 @@ const Dashboard = () => {
- diff --git a/frontend/src/pages/Login.tsx b/frontend/src/pages/Login.tsx index 5c141133..2e12e5a4 100644 --- a/frontend/src/pages/Login.tsx +++ b/frontend/src/pages/Login.tsx @@ -18,8 +18,8 @@ import buildingPhoto from '../assets/ritchennai.webp'; const Login = () => { const [role, setRole] = useState<'manager' | 'master'>('manager'); const [showPassword, setShowPassword] = useState(false); - const [username, setUsername] = useState('admin'); - const [password, setPassword] = useState('admin'); + const [username, setUsername] = useState(''); + const [password, setPassword] = useState(''); const navigate = useNavigate(); // Ensure any previous session is completely wiped out when arriving at the login screen diff --git a/frontend/src/pages/PurchaseAnalytics.tsx b/frontend/src/pages/PurchaseAnalytics.tsx index c7bd6037..8d788de3 100644 --- a/frontend/src/pages/PurchaseAnalytics.tsx +++ b/frontend/src/pages/PurchaseAnalytics.tsx @@ -169,7 +169,7 @@ const PurchaseAnalytics = () => { if (isLoading) { return (
- +

Calculating Market Analytics...

); @@ -180,12 +180,12 @@ const PurchaseAnalytics = () => { {/* Header */}
-

Purchase Analytics

+

Purchase Analytics

- + Start: {format(dateRange.start, 'yyyy-MM-dd')} - + End: {format(dateRange.end, 'yyyy-MM-dd')}
@@ -193,7 +193,7 @@ const PurchaseAnalytics = () => {
@@ -230,7 +230,7 @@ const PurchaseAnalytics = () => { setSearchTerm(e.target.value)} /> @@ -253,7 +253,7 @@ const PurchaseAnalytics = () => { ) : ( filteredAnalytics.map((item, idx) => ( -

{item.product}

+

{item.product}

{item.qty} ₹{item.basePrice.toFixed(2)} @@ -285,7 +285,7 @@ const PurchaseAnalytics = () => {
-

Purchases

+

Purchases

Summary

@@ -88,7 +88,7 @@ const PurchaseSummary = () => { @@ -118,7 +118,7 @@ const PurchaseSummary = () => { ))} -
+
@@ -173,7 +173,7 @@ const PurchaseSummary = () => {
- +
@@ -205,7 +205,7 @@ const PurchaseSummary = () => { ₹{bill.balance.toLocaleString()} - ₹{bill.amount.toLocaleString()} + ₹{bill.amount.toLocaleString()} ))} diff --git a/frontend/src/pages/StoreDashboard.tsx b/frontend/src/pages/StoreDashboard.tsx index dd5109cb..cb704305 100644 --- a/frontend/src/pages/StoreDashboard.tsx +++ b/frontend/src/pages/StoreDashboard.tsx @@ -100,7 +100,7 @@ const StoreDashboard = () => { -

Store Dashboard

+

Store Dashboard

Good morning, RIT Canteen

@@ -108,7 +108,7 @@ const StoreDashboard = () => {
-
@@ -116,7 +116,7 @@ const StoreDashboard = () => {
-
@@ -132,7 +132,7 @@ const StoreDashboard = () => {
-
+
A
@@ -148,11 +148,11 @@ const StoreDashboard = () => { key={tab} title={`Visualize ${tab.toLowerCase()} throughput data`} onClick={() => setActiveTab(tab)} - className={`pb-4 text-[11px] font-black uppercase tracking-widest transition-all relative ${activeTab === tab ? 'text-[#521c4b]' : 'text-slate-400 hover:text-slate-600'}`} + className={`pb-4 text-[11px] font-black uppercase tracking-widest transition-all relative ${activeTab === tab ? 'text-[#0f4475]' : 'text-slate-400 hover:text-slate-600'}`} > {tab} {activeTab === tab && ( - + )} ))} @@ -224,18 +224,18 @@ const StoreDashboard = () => { key={range} title={`Filter metrics by ${range.toLowerCase()}`} onClick={() => setTimeRange(range)} - className={`whitespace-nowrap px-2 py-2 text-[10px] font-black uppercase tracking-tighter transition-all relative ${timeRange === range ? 'text-[#521c4b]' : 'text-slate-400 hover:text-slate-600'}`} + className={`whitespace-nowrap px-2 py-2 text-[10px] font-black uppercase tracking-tighter transition-all relative ${timeRange === range ? 'text-[#0f4475]' : 'text-slate-400 hover:text-slate-600'}`} > {range} {timeRange === range && ( - + )} ))}
{/* Total Orders Card */} -
+
@@ -249,9 +249,9 @@ const StoreDashboard = () => {
{/* Expenses Card */} -
+
-
+

Expenses

@@ -297,7 +297,7 @@ const StoreDashboard = () => { {item.name}
-

{item.category}

+

{item.category}

{item.name}

@@ -328,7 +328,7 @@ const StoreDashboard = () => {
-