Skip to content

Commit 844253e

Browse files
add swagger and token verification
1 parent 9964277 commit 844253e

29 files changed

Lines changed: 828 additions & 222 deletions

client/app/(auth)/login/login.tsx

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,13 @@ export default function LoginPage() {
3232

3333
const { mutate, isPending, isSuccess, isError } = useMutation({
3434
mutationFn: loginUser,
35+
// Update the onSuccess handler:
3536
onSuccess: (data) => {
3637
setSuccessMsg("Login successfully!");
37-
console.log("data==>", data);
38+
localStorage.setItem("token", data.token);
39+
setTokenState(data.token); // This will trigger verification in context
3840
reset();
39-
localStorage.setItem("token",data.token)
40-
setTokenState(data.token)
41-
setTimeout(() => {
42-
setIsLogin(false);
43-
}, 2000);
41+
setTimeout(() => setIsLogin(false), 2000);
4442
},
4543
onError: (err: any) => {
4644
setErrorMsg(err.message || "Something went wrong");
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
'use client'
2+
import axios from 'axios';
3+
4+
const API_BASE = 'http://localhost:4000/api';
5+
6+
export const authentication = async (token: string | null) => {
7+
if (!token) return { success: false };
8+
9+
try {
10+
const response = await axios.get(`${API_BASE}/authenticate`, {
11+
headers: { Authorization: `Bearer ${token}` },
12+
});
13+
14+
return {
15+
data: response.data
16+
};
17+
} catch (error) {
18+
console.error("Authentication failed:", error);
19+
return { success: false };
20+
}
21+
}

client/app/_lib/services/viewService.tsx

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,12 @@ import axios from "axios";
44
const API_BASE = 'http://localhost:4000/api';
55
export const getPlaceViewDetails = async ({
66
queryKey,
7-
}: QueryFunctionContext<[string, string, string]>) => {
8-
const [, token, id] = queryKey;
7+
}: QueryFunctionContext<[string, string]>) => {
8+
const [, id] = queryKey;
99

10-
console.log("Frontend Token:", token);
1110
console.log("Feature ID:", id);
1211

13-
const response = await axios.get(`${API_BASE}/featuresDetails?featureId=${id}`, {
14-
headers: {
15-
Authorization: `Bearer ${token}`,
16-
},
17-
});
12+
const response = await axios.get(`${API_BASE}/featuresDetails?featureId=${id}`);
1813

1914
return response.data;
2015
};

client/app/_lib/styles/sidebar.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.menu{
2+
@media (width <= 760px) {
3+
display: none !important;
4+
}
5+
}

client/app/_lib/styles/site.module.css

Whitespace-only changes.

client/app/components/common/modal.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
'use client';
22

33
import React, { useEffect, useState } from 'react';
4-
import '../../_lib/styles/modal.css';
54
import { createPortal } from 'react-dom';
65

76
interface ModalProps {
@@ -16,10 +15,10 @@ function Modal({ children }: ModalProps) {
1615
setPortalRoot(el);
1716
}, []);
1817

19-
if (!portalRoot) return null; // Wait until DOM is ready
18+
if (!portalRoot) return null;
2019

2120
return createPortal(
22-
<div id="myModal" className="modal">
21+
<div id="myModal" className="fixed inset-0 z-50 flex items-center justify-center bg-opacity-40 px-4 sm:px-6">
2322
{children}
2423
</div>,
2524
portalRoot

client/app/components/layout/Header.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
'use client';
2-
import { BellIcon, UserCircle, LogIn, LogOut, UserPlus, Link } from 'lucide-react';
2+
import { BellIcon, UserCircle, LogOut, UserPlus } from 'lucide-react';
33
import { useState, useRef, useEffect } from 'react';
44
import { useRouter } from 'next/navigation';
55
import { useContextAPI } from '../../_lib/context/contextAPI';
6+
67
const Header = () => {
8+
79
const {setIsLogin,setIsSignUp,setIsProfile, setTokenState} = useContextAPI()
810
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
911
const dropdownRef = useRef<HTMLDivElement>(null);
10-
const router = useRouter()
12+
const router = useRouter();
13+
1114
// Close dropdown when clicking outside or pressing Escape
1215
useEffect(() => {
1316
const handleClickOutside = (event: MouseEvent) => {
@@ -46,6 +49,7 @@ const Header = () => {
4649
localStorage.removeItem('token');
4750
setTokenState('')
4851
}
52+
router.push('/')
4953
};
5054

5155
const handleSignIn = () => {

client/app/components/layout/Sidebar/Sidebar.tsx

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ import Link from 'next/link';
33
import { usePathname } from 'next/navigation';
44
import { Map, ChevronsLeft, ChevronsRight, HeartPlus } from 'lucide-react';
55
import { useContextAPI } from '../../../_lib/context/contextAPI';
6-
6+
import '../../../_lib/styles/sidebar.css'
77
export default function Sidebar() {
88
const pathname = usePathname();
99
const { isCollapsed, toggleSidebar, token } = useContextAPI();
10-
10+
console.log("sidebar token=>",token)
1111
const navItems = [
1212
{ label: 'Map', href: '/', icon: <Map size={20} /> },
1313
...(token ? [{ label: 'Favorites', href: '/favorites', icon: <HeartPlus size={20} /> }] : []),
@@ -16,11 +16,11 @@ export default function Sidebar() {
1616
return (
1717
<aside className={`
1818
h-screen bg-white border-r border-gray-200 py-3 px-2 flex flex-col gap-y-6
19-
transition-all duration-300 ease-in-out shadow-sm shadow-gray-200
20-
${isCollapsed ? 'w-[60px]' : 'w-[200px]'}
19+
transition-all duration-300 ease-in-out shadow-sm shadow-gray-200
20+
${isCollapsed ? 'w-[60px]' : ' w-[60px] md:w-[200px]'}
2121
`}>
22-
<div className={`flex ${isCollapsed ? 'flex-col' : ''} justify-between items-center`}>
23-
<span className={`text-base font-medium ${isCollapsed && 'mt-2'}`}>Chemnitz Culture</span>
22+
<div className={`flex ${isCollapsed ? 'flex-col' : ' flex-col md:flex-row'} justify-between items-center`}>
23+
<span className={`text-2xl font-bold ml-2 ${isCollapsed && 'mt-2'}`}>KultLink</span>
2424
<button
2525
onClick={toggleSidebar}
2626
className="p-1 rounded-md hover:bg-gray-100 transition-colors hover:cursor-pointer"
@@ -45,17 +45,7 @@ export default function Sidebar() {
4545
{icon}
4646
</span>
4747
{!isCollapsed && (
48-
<span className="hover:cursor-pointer">{label}</span>
49-
)}
50-
{isCollapsed && (
51-
<span className="
52-
absolute left-full ml-4 px-2 py-1 rounded-md
53-
bg-gray-800 text-white text-sm
54-
invisible opacity-0 group-hover:visible group-hover:opacity-100
55-
transition-opacity duration-200
56-
">
57-
{label}
58-
</span>
48+
<span className=" menu md:block text-sm hover:cursor-pointer transition-opacity duration-200">{label}</span>
5949
)}
6050
</Link>
6151
))}
@@ -64,7 +54,7 @@ export default function Sidebar() {
6454
{isCollapsed && (
6555
<div className="mt-auto text-center">
6656
<span className="text-xs text-gray-500 rotate-90 inline-block origin-center whitespace-nowrap">
67-
Chemnitz
57+
KultLink
6858
</span>
6959
</div>
7060
)}

0 commit comments

Comments
 (0)