Skip to content
This repository was archived by the owner on Nov 23, 2025. It is now read-only.
Merged

Dev #37

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
dcae9a6
chore: trigger GitOps pipeline (empty commit)
RandithaK Nov 15, 2025
b410798
feat: enhance PayHere payment object with additional fields and logging
RandithaK Nov 15, 2025
6e6b5ad
Merge pull request #33 from TechTorque-2025/bigfix-payment-integration
RandithaK Nov 15, 2025
96d18b5
Merge pull request #32 from TechTorque-2025/feat/gitops-workflow
RandithaK Nov 15, 2025
d04c054
feat: update AIChatWidget to use shared API client for chat requests …
RandithaK Nov 15, 2025
53417f8
feat: implement toast notifications across various pages and components
ChamodiSandunika Nov 20, 2025
a4be154
feat: enhance light and dark theme color variables for improved UI co…
Pramudi02 Nov 20, 2025
2a97e98
style: update error message styling for consistency across components
Pramudi02 Nov 20, 2025
06eb1d2
style: unify error message styling across dashboards and payment gate…
Pramudi02 Nov 20, 2025
60270fc
style: Refactor dashboard components for improved styling and consist…
Pramudi02 Nov 20, 2025
fb0e09b
style: update branding and icon styling across authentication pages
Pramudi02 Nov 20, 2025
ec02ad9
style: refactor component styling for readability across dashboard pages
Pramudi02 Nov 20, 2025
6013fc9
style: update error message styling, vehicle and profile pages
Pramudi02 Nov 20, 2025
db00fa7
Merge branch 'dev' into style/lightmode
Pramudi02 Nov 21, 2025
9cc42ae
Merge pull request #35 from TechTorque-2025/style/lightmode
Pramudi02 Nov 21, 2025
4d0b56e
Merge pull request #34 from TechTorque-2025/style-toast_messages
ChamodiSandunika Nov 21, 2025
97e9022
style: remove demo user information from login page
Nov 21, 2025
9553316
Merge pull request #36 from TechTorque-2025/fix-loginpage
Dhanuja416 Nov 21, 2025
9b0c77b
fix: prevent `apiClient` redirect on 401 for login requests and add e…
RandithaK Nov 21, 2025
34dd3fd
fix: improve error handling in authService.login to handle Axios errors
RandithaK Nov 21, 2025
87b8e57
fix: update service type handling in appointment booking to use form …
RandithaK Nov 21, 2025
8b47b20
fix: adjust notification dropdown position to improve visibility
RandithaK Nov 21, 2025
161ec81
fix: enhance notification button styling with ripple effect and hover…
RandithaK Nov 21, 2025
f6d96f5
fix: improve data handling in service responses to ensure consistent …
RandithaK Nov 22, 2025
e73fb2b
Refactor UI components to use theme variables for consistent styling
RandithaK Nov 22, 2025
d64e181
fix: add suppressHydrationWarning to html tag for improved hydration …
RandithaK Nov 22, 2025
95655ee
fix: refactor ThemeToggle component import and clean up unused code a…
RandithaK Nov 22, 2025
8a18d7c
fix: update hover border styles in CustomerDashboard and adjust gradi…
RandithaK Nov 22, 2025
9922d47
fix: enhance ReportsPage functionality with report loading and downlo…
RandithaK Nov 23, 2025
6df926a
fix: simplify report type options in ReportsPage for better clarity a…
RandithaK Nov 23, 2025
8e74de2
fix: update styling in AIChatWidget for improved visual consistency a…
RandithaK Nov 23, 2025
9e0e216
fix: update Next.js version to 16.0.3 for improved performance and fe…
RandithaK Nov 23, 2025
5c4b864
fix: adjust position of notification dropdown for better visibility
RandithaK Nov 23, 2025
1f6ce42
fix: relocate AI chat widget to dashboard layout for consistent acces…
RandithaK Nov 23, 2025
1943293
fix: enhance error handling in Notification context and API client fo…
RandithaK Nov 23, 2025
2a9012e
fix: enhance error handling in response interceptor and add unit test…
RandithaK Nov 23, 2025
5a964a0
fix: remove outdated apiClient tests to streamline codebase
RandithaK Nov 23, 2025
738be5c
fix: improve error handling in user creation process for better clari…
RandithaK Nov 23, 2025
a067e5f
fix: enhance error handling in AI chat widget and API client for impr…
RandithaK Nov 23, 2025
2e11791
fix: enhance error logging in AI chat widget to sanitize messages for…
RandithaK Nov 23, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,26 @@ This repository contains the source code for the TechTorque 2025 customer and em
npm run setup-hooks
```
This configures automatic linting on commit and build checking on push. See [GIT_HOOKS.md](GIT_HOOKS.md) for details.

### 🔌 Environment

- The frontend expects an API base to be available at runtime. You can configure this via the
`NEXT_PUBLIC_API_BASE_URL` environment variable. When not set, the runtime defaults to
`http://localhost:8080` (useful in development).

- The AI chat widget reaches the AI chat proxy at `/api/v1/ai/chat` (or `{{NEXT_PUBLIC_API_BASE_URL}}/api/v1/ai/chat` when the public API base is set). This ensures the frontend talks to the configured API gateway or the local Next.js proxy.

### 🎨 Theme & Styling (Centralized)

- A single global stylesheet lives at `src/app/globals.css` and contains all theme variables for light & dark mode, plus utility classes like:
- `.theme-button-primary`, `.theme-button-secondary` — semantic buttons
- `.theme-bg-primary`, `.theme-text-primary`, `.theme-border`, etc — consistent building blocks
- `.automotive-accent`, `.accent-badge`, `.text-gradient-accent`, `.progress-accent` — accent utilities
Comment on lines +63 to +65
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix markdown list indentation.

The nested list items use 3-space indentation but should use 2 spaces per Markdown best practices.

Apply this diff to fix the indentation:

-- A single global stylesheet lives at `src/app/globals.css` and contains all theme variables for light & dark mode, plus utility classes like:
-   - `.theme-button-primary`, `.theme-button-secondary` — semantic buttons
-   - `.theme-bg-primary`, `.theme-text-primary`, `.theme-border`, etc — consistent building blocks
-   - `.automotive-accent`, `.accent-badge`, `.text-gradient-accent`, `.progress-accent` — accent utilities
+- A single global stylesheet lives at `src/app/globals.css` and contains all theme variables for light & dark mode, plus utility classes like:
+  - `.theme-button-primary`, `.theme-button-secondary` — semantic buttons
+  - `.theme-bg-primary`, `.theme-text-primary`, `.theme-border`, etc — consistent building blocks
+  - `.automotive-accent`, `.accent-badge`, `.text-gradient-accent`, `.progress-accent` — accent utilities

-- Quick checks added:
-   - `npm run check:theme` — verifies `globals.css` and `ThemeContext` contain expected hooks and variables.
-   - `npm run check:colors` — scans `src/` for hardcoded hex/rgb color usage (ignores `globals.css`).
+- Quick checks added:
+  - `npm run check:theme` — verifies `globals.css` and `ThemeContext` contain expected hooks and variables.
+  - `npm run check:colors` — scans `src/` for hardcoded hex/rgb color usage (ignores `globals.css`).

Based on static analysis hints.

Also applies to: 70-71

🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

63-63: Unordered list indentation
Expected: 2; Actual: 3

(MD007, ul-indent)


64-64: Unordered list indentation
Expected: 2; Actual: 3

(MD007, ul-indent)


65-65: Unordered list indentation
Expected: 2; Actual: 3

(MD007, ul-indent)

🤖 Prompt for AI Agents
In README.md around lines 63-65 (and also apply the same fix to lines 70-71),
the nested markdown list items are indented with 3 spaces instead of the
expected 2; update each nested list line to use 2-space indentation so nested
bullets align with Markdown best practices (change each leading indentation from
three spaces to two spaces) and verify surrounding list markers and spacing
remain consistent.


- Theme switching is implemented using `src/app/contexts/ThemeContext.tsx` plus a small pre-hydration script in `src/app/layout.tsx` (so the app applies the saved system preference or previously saved theme before React mounts to avoid flashes).

- Quick checks added:
- `npm run check:theme` — verifies `globals.css` and `ThemeContext` contain expected hooks and variables.
- `npm run check:colors` — scans `src/` for hardcoded hex/rgb color usage (ignores `globals.css`).

If you're adding new UI colors, add variables to `src/app/globals.css` and use the semantic utility classes (or create new ones) — this keeps light/dark behavior centralized and consistent across the app.
80 changes: 40 additions & 40 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@
"build": "next build --turbopack",
"start": "next start",
"lint": "eslint",
"check:colors": "node ./scripts/check-hardcoded-colors.js",
"check:theme": "node ./scripts/check-theme-setup.js",
"setup-hooks": "chmod +x .githooks/pre-commit .githooks/pre-push && git config core.hooksPath .githooks && echo '✅ Git hooks configured successfully!'"
},
"dependencies": {
"@stomp/stompjs": "^7.2.1",
"axios": "^1.12.2",
"js-cookie": "^3.0.5",
"lucide-react": "^0.553.0",
"next": "^16.0.1",
"next": "^16.0.3",
"react": "19.1.0",
"react-dom": "19.1.0",
"sockjs-client": "^1.6.1"
Expand Down
35 changes: 35 additions & 0 deletions scripts/check-hardcoded-colors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/usr/bin/env node
import fs from 'fs'
import path from 'path'

const root = path.resolve(__dirname, '..', 'src')
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

__dirname is not available in ES modules.

Line 5 uses __dirname, but this script uses ES module syntax (import statements). In ES modules, __dirname is undefined and will cause a runtime error.

Apply this diff to fix:

+import { fileURLToPath } from 'url'
+import { dirname } from 'path'
+
+const __filename = fileURLToPath(import.meta.url)
+const __dirname = dirname(__filename)
+
-const root = path.resolve(__dirname, '..', 'src')
+const root = path.resolve(__dirname, '..', 'src')
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const root = path.resolve(__dirname, '..', 'src')
import { fileURLToPath } from 'url'
import { dirname } from 'path'
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)
const root = path.resolve(__dirname, '..', 'src')
🤖 Prompt for AI Agents
In scripts/check-hardcoded-colors.js around line 5, __dirname is used but this
file is an ES module so __dirname is undefined; replace use of __dirname by
deriving the directory from import.meta.url: import fileURLToPath from 'url' (or
destructure fileURLToPath) and compute const __filename =
fileURLToPath(import.meta.url) and const __dirname = path.dirname(__filename),
then set root = path.resolve(__dirname, '..', 'src'); add the import for
fileURLToPath at top and remove any direct __dirname usages.


const hexRe = /#[0-9a-fA-F]{3,6}/g
const rgbRe = /rgba?\(/gi

function walk(dir) {
const entries = fs.readdirSync(dir, { withFileTypes: true })
for (const e of entries) {
const full = path.join(dir, e.name)
if (e.isDirectory()) {
walk(full)
} else if (e.isFile()) {
if (full.endsWith('globals.css')) continue
if (!full.endsWith('.css') && !full.endsWith('.tsx') && !full.endsWith('.ts') && !full.endsWith('.jsx') && !full.endsWith('.js') && !full.endsWith('.svg')) continue
const content = fs.readFileSync(full, 'utf8')
const hex = content.match(hexRe)
const rgb = content.match(rgbRe)
if ((hex && hex.length) || (rgb && rgb.length)) {
console.log(`Found in ${path.relative(process.cwd(), full)} -> hex:${hex ? hex.join(',') : '0'} rgb:${rgb ? rgb.length : 0}`)
}
}
}
}

try {
walk(root)
console.log('\nSearch complete — open the above files and replace hardcoded colors with theme variables in src/app/globals.css.')
} catch (err) {
console.error(err)
process.exit(1)
}
27 changes: 27 additions & 0 deletions scripts/check-theme-setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/usr/bin/env node
import fs from 'fs'
import path from 'path'

const globals = fs.readFileSync(path.resolve(__dirname, '../src/app/globals.css'), 'utf8')
const themeContext = fs.readFileSync(path.resolve(__dirname, '../src/app/contexts/ThemeContext.tsx'), 'utf8')

Comment on lines +1 to +7
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Fix ESM __dirname usage so the script can actually run

With import syntax, Node will treat this as an ES module (in a "type": "module" project), where __dirname is not defined. That means this script will currently error out instead of running your checks.

Define __dirname from import.meta.url (or drop __dirname entirely and resolve from process.cwd()), e.g.:

-#!/usr/bin/env node
-import fs from 'fs'
-import path from 'path'
-
-const globals = fs.readFileSync(path.resolve(__dirname, '../src/app/globals.css'), 'utf8')
-const themeContext = fs.readFileSync(path.resolve(__dirname, '../src/app/contexts/ThemeContext.tsx'), 'utf8')
+#!/usr/bin/env node
+import fs from 'fs';
+import path from 'path';
+import { fileURLToPath } from 'url';
+
+const __filename = fileURLToPath(import.meta.url);
+const __dirname = path.dirname(__filename);
+
+const globals = fs.readFileSync(path.resolve(__dirname, '../src/app/globals.css'), 'utf8');
+const themeContext = fs.readFileSync(path.resolve(__dirname, '../src/app/contexts/ThemeContext.tsx'), 'utf8');
🤖 Prompt for AI Agents
In scripts/check-theme-setup.js around lines 1 to 7, the script uses __dirname
which is undefined in ESM; replace its usage by deriving a directory from
import.meta.url (e.g. const __filename = fileURLToPath(import.meta.url) and
const __dirname = path.dirname(__filename)) or switch to resolving paths from
process.cwd(); if you choose the import.meta.url approach, add the required
import from 'url' (fileURLToPath) and then update the path.resolve calls to use
the computed __dirname variable.

let ok = true

function assert(cond, msg) {
if (!cond) {
console.error('FAIL:', msg)
ok = false
} else {
console.log('OK:', msg)
}
}

assert(globals.includes(':root'), 'globals.css has :root declarations')
assert(globals.includes('html.dark'), 'globals.css has html.dark overrides')
assert(globals.includes('--accent-primary'), 'globals.css defines --accent-primary var')

assert(themeContext.includes("localStorage.getItem('theme')"), 'ThemeContext reads localStorage')
assert(themeContext.includes("document.documentElement.classList"), 'ThemeContext manipulates document.documentElement classList')

if (!ok) process.exit(1)
console.log('\nTheme setup basic checks passed — globals.css + ThemeContext look correctly configured.')
8 changes: 4 additions & 4 deletions src/app/admin/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ export default function AdminDashboard() {
<div className="flex gap-4">
<button
onClick={() => router.push("/profile")}
className="px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg transition-colors"
className="px-4 py-2 theme-button-primary rounded-lg transition-colors"
>
My Profile
</button>
Expand All @@ -108,13 +108,13 @@ export default function AdminDashboard() {
</div>

{error && (
<div className="mb-6 p-4 bg-red-50 dark:bg-red-900/20 rounded-lg border border-red-200 dark:border-red-800">
<p className="text-sm text-red-600 dark:text-red-400">{error}</p>
<div className="mb-6 theme-alert-danger">
<p className="text-sm">{error}</p>
</div>
)}

{success && (
<div className="mb-6 p-4 bg-green-50 dark:bg-green-900/20 rounded-lg border border-green-200 dark:border-green-800">
<div className="mb-6 theme-alert-success">
<p className="text-sm text-green-600 dark:text-green-400">
{success}
</p>
Expand Down
8 changes: 4 additions & 4 deletions src/app/auth/forgot-password/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import Link from 'next/link'
import authService from '../../../services/authService'
import ThemeToggle from '../../components/ThemeToggle'

const Icon = ({ d, size = 10 }: { d: string; size?: number }) => ( <svg className={`w-${size} h-${size} text-white`} fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d={d} /></svg>);
const BoltIcon = ({size = 10}) => <Icon d="M13 10V3L4 14h7v7l9-11h-7z" size={size} />;
// (removed unused Icon helper)


// --- Forgot Password Page Component ---
export default function ForgotPasswordPage() {
Expand Down Expand Up @@ -46,7 +46,7 @@ export default function ForgotPasswordPage() {
<header className="sticky-header shadow-lg border-b theme-border">
<div className="max-w-7xl mx-auto py-4 px-4 sm:px-6 lg:px-8">
<div className="flex justify-between items-center">
<Link href="/" className="flex items-center space-x-3 group"><div className="w-12 h-12 rounded-full bg-gradient-to-r from-blue-500 to-cyan-400 flex items-center justify-center shadow-lg transform transition-transform duration-300 group-hover:scale-110"><BoltIcon size={6} /></div><h1 className="text-2xl font-bold theme-text-primary hidden sm:block">TechTorque Auto</h1></Link>
<Link href="/" className="flex items-center space-x-3 group"><div className="automotive-accent w-12 h-12 rounded-full flex items-center justify-center shadow-lg transform transition-transform duration-300 group-hover:scale-110"><span className="text-white font-bold text-lg">TT</span></div><h1 className="text-2xl font-bold theme-text-primary hidden sm:block">TechTorque</h1></Link>
<div className="flex items-center space-x-4"><Link href="/auth/login" className="theme-link hidden md:inline-block">Back to Sign In</Link><ThemeToggle /></div>
</div>
</div>
Expand Down Expand Up @@ -74,7 +74,7 @@ export default function ForgotPasswordPage() {
</div>
{error && (
<div className="mb-6 p-4 bg-red-50 dark:bg-red-900/20 rounded-lg border border-red-200 dark:border-red-800">
<p className="text-sm text-red-600 dark:text-red-400">{error}</p>
<p className="text-sm theme-text-danger">{error}</p>
</div>
)}
<form className="space-y-6" onSubmit={handleSubmit}>
Expand Down
27 changes: 7 additions & 20 deletions src/app/auth/login/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,8 @@ import authService from '../../../services/authService';
import type { LoginRequest } from '../../../types/api';
import ThemeToggle from '../../components/ThemeToggle';

// Icon Components
const Icon = ({ d, size = 10 }: { d: string; size?: number }) => (
<svg className={`w-${size} h-${size} text-white`} fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d={d} />
</svg>
);
const BoltIcon = ({size = 10}) => <Icon d="M13 10V3L4 14h7v7l9-11h-7z" size={size} />;
// (removed unused Icon helper)

const LockClosedIcon = () => <svg className="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" /></svg>;


Expand Down Expand Up @@ -74,11 +69,11 @@ export default function LoginPage() {
<div className="max-w-7xl mx-auto py-4 px-4 sm:px-6 lg:px-8">
<div className="flex justify-between items-center">
<Link href="/" className="flex items-center space-x-3 group">
<div className="w-12 h-12 rounded-full bg-gradient-to-r from-blue-500 to-cyan-400 flex items-center justify-center shadow-lg transform transition-transform duration-300 group-hover:scale-110">
<BoltIcon size={6} />
<div className="automotive-accent w-12 h-12 rounded-full flex items-center justify-center shadow-lg transform transition-transform duration-300 group-hover:scale-110">
<span className="text-white font-bold text-lg">TT</span>
</div>
<h1 className="text-2xl font-bold theme-text-primary hidden sm:block">
TechTorque Auto
TechTorque
</h1>
</Link>
<div className="flex items-center space-x-4">
Expand All @@ -104,15 +99,7 @@ export default function LoginPage() {
<p className="mt-4 text-lg theme-text-muted">
Sign in to access your dashboard.
</p>
<div className="mt-6 p-4 bg-blue-50 dark:bg-blue-900/20 rounded-lg border border-blue-200 dark:border-blue-800">
<p className="text-sm font-semibold theme-text-primary mb-2">Demo Users (Real Backend):</p>
<div className="text-xs theme-text-muted space-y-1">
<p><strong>SuperAdmin:</strong> superadmin / superadmin123</p>
<p><strong>Admin:</strong> admin / admin123</p>
<p><strong>Employee:</strong> employee / emp123</p>
<p><strong>Customer:</strong> customer / cust123</p>
</div>
</div>

</div>

<form className="space-y-6" onSubmit={handleSubmit}>
Expand Down Expand Up @@ -160,7 +147,7 @@ export default function LoginPage() {
</form>
{error && (
<div role="alert" className="mt-4 p-4 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg">
<p className="text-sm text-red-600 dark:text-red-400 mb-2">{error}</p>
<p className="text-sm theme-text-danger mb-2">{error}</p>
{unverifiedEmail && (
<Link
href={`/auth/resend-verification?email=${encodeURIComponent(unverifiedEmail)}`}
Expand Down
Loading