diff --git a/SerpentRace_Backend/src/Api/routers/adminRouter.ts b/SerpentRace_Backend/src/Api/routers/adminRouter.ts index f413e203..46a3861d 100644 --- a/SerpentRace_Backend/src/Api/routers/adminRouter.ts +++ b/SerpentRace_Backend/src/Api/routers/adminRouter.ts @@ -141,32 +141,32 @@ router.get('/users/:userId', }); // Search users including soft-deleted ones -// router.get('/users/search/:searchTerm', -// adminRequired, -// ValidationMiddleware.validateStringLength({ searchTerm: { min: 2, max: 100 } }), -// async (req: Request, res: Response) => { -// try { -// const { searchTerm } = req.params; -// const includeDeleted = req.query.includeDeleted === 'true'; +router.get('/users/search/:searchTerm', + adminRequired, + ValidationMiddleware.validateStringLength({ searchTerm: { min: 2, max: 100 } }), + async (req: Request, res: Response) => { + try { + const { searchTerm } = req.params; + const includeDeleted = req.query.includeDeleted === 'true'; -// logRequest('Admin search users endpoint accessed', req, res, { searchTerm, includeDeleted }); + logRequest('Admin search users endpoint accessed', req, res, { searchTerm, includeDeleted }); -// const users = includeDeleted -// ? await container.userRepository.searchIncludingDeleted(searchTerm) -// : await container.userRepository.search(searchTerm); + const users = includeDeleted + ? await container.userRepository.searchIncludingDeleted(searchTerm) + : await container.userRepository.search(searchTerm); -// logRequest('Admin user search completed', req, res, { -// searchTerm, -// resultCount: Array.isArray(users) ? users.length : (users.totalCount || 0), -// includeDeleted -// }); + logRequest('Admin user search completed', req, res, { + searchTerm, + resultCount: Array.isArray(users) ? users.length : (users.totalCount || 0), + includeDeleted + }); -// res.json(users); -// } catch (error) { -// logError('Admin search users endpoint error', error as Error, req, res); -// res.status(500).json({ error: 'Internal server error' }); -// } -// }); + res.json(users); + } catch (error) { + logError('Admin search users endpoint error', error as Error, req, res); + res.status(500).json({ error: 'Internal server error' }); + } +}); // Update any user (admin only) router.patch('/users/:userId', @@ -213,6 +213,32 @@ router.patch('/users/:userId', } }); +// Activate user (admin only) +router.post('/users/:userId/activate', + adminRequired, + ValidationMiddleware.validateUUIDFormat(['userId']), + async (req: Request, res: Response) => { + try { + const targetUserId = req.params.userId; + const adminUserId = (req as any).user.userId; + + logRequest('Admin activate user endpoint accessed', req, res, { adminUserId, targetUserId }); + + const result = await container.activateUserCommandHandler.execute({ id: targetUserId }); + + if (!result) { + return res.status(404).json({ error: 'User not found' }); + } + + logAuth('User activated by admin', targetUserId, { adminUserId }, req, res); + res.json({ message: 'User activated successfully', user: result }); + + } catch (error) { + logError('Admin activate user endpoint error', error as Error, req, res); + res.status(500).json({ error: 'Internal server error' }); + } +}); + // Deactivate user (admin only) router.post('/users/:userId/deactivate', adminRequired, diff --git a/SerpentRace_Backend/src/Application/DTOs/Mappers/DeckMapper.ts b/SerpentRace_Backend/src/Application/DTOs/Mappers/DeckMapper.ts index d1536a1b..25d276c0 100644 --- a/SerpentRace_Backend/src/Application/DTOs/Mappers/DeckMapper.ts +++ b/SerpentRace_Backend/src/Application/DTOs/Mappers/DeckMapper.ts @@ -1,7 +1,6 @@ import { DeckAggregate } from '../../../Domain/Deck/DeckAggregate'; import { UserAggregate } from '../../../Domain/User/UserAggregate'; import { CreateDeckDto, UpdateDeckDto, ShortDeckDto, DetailDeckDto } from '../DeckDto'; -import e from 'express'; export class DeckMapper { static toShortDto(deck: DeckAggregate, userId?: string): ShortDeckDto { diff --git a/SerpentRace_Backend/src/Application/DTOs/Mappers/OrganizationMapper.ts b/SerpentRace_Backend/src/Application/DTOs/Mappers/OrganizationMapper.ts index 695b17ee..70ff5352 100644 --- a/SerpentRace_Backend/src/Application/DTOs/Mappers/OrganizationMapper.ts +++ b/SerpentRace_Backend/src/Application/DTOs/Mappers/OrganizationMapper.ts @@ -22,7 +22,7 @@ export class OrganizationMapper { contactemail: org.contactemail, state: org.state, regdate: org.regdate, - updatedate: org.updatedate, + updateDate: org.updateDate, url: org.url, userinorg: org.userinorg, maxOrganizationalDecks: org.maxOrganizationalDecks, diff --git a/SerpentRace_Backend/src/Application/DTOs/OrganizationDto.ts b/SerpentRace_Backend/src/Application/DTOs/OrganizationDto.ts index e82c27f6..c1eb4aaf 100644 --- a/SerpentRace_Backend/src/Application/DTOs/OrganizationDto.ts +++ b/SerpentRace_Backend/src/Application/DTOs/OrganizationDto.ts @@ -27,7 +27,7 @@ export interface DetailOrganizationDto { contactemail: string; state: number; regdate: Date; - updatedate: Date; + updateDate: Date; url: string | null; userinorg: number; maxOrganizationalDecks: number | null; diff --git a/SerpentRace_Backend/src/Application/Services/DIContainer.ts b/SerpentRace_Backend/src/Application/Services/DIContainer.ts index 7c6af860..d4a5fd36 100644 --- a/SerpentRace_Backend/src/Application/Services/DIContainer.ts +++ b/SerpentRace_Backend/src/Application/Services/DIContainer.ts @@ -39,6 +39,7 @@ import { ProcessOrgAuthCallbackCommandHandler } from '../Organization/commands/P import { CreateContactCommandHandler } from '../Contact/commands/CreateContactCommandHandler'; import { UpdateContactCommandHandler } from '../Contact/commands/UpdateContactCommandHandler'; import { DeleteContactCommandHandler } from '../Contact/commands/DeleteContactCommandHandler'; +import { ActivateUserCommandHandler } from '../User/commands/ActivateUserCommandHandler'; // Query Handlers import { GetUserByIdQueryHandler } from '../User/queries/GetUserByIdQueryHandler'; @@ -121,6 +122,7 @@ export class DIContainer { private _updateContactCommandHandler: UpdateContactCommandHandler | null = null; private _deleteContactCommandHandler: DeleteContactCommandHandler | null = null; private _generateBoardCommandHandler: GenerateBoardCommandHandler | null = null; + private _activateUserCommandHandler: ActivateUserCommandHandler | null = null; // Query Handlers private _getUserByIdQueryHandler: GetUserByIdQueryHandler | null = null; @@ -306,6 +308,13 @@ export class DIContainer { return this._deactivateUserCommandHandler; } + public get activateUserCommandHandler(): ActivateUserCommandHandler { + if (!this._activateUserCommandHandler) { + this._activateUserCommandHandler = new ActivateUserCommandHandler(this.userRepository); + } + return this._activateUserCommandHandler; + } + public get deleteUserCommandHandler(): DeleteUserCommandHandler { if (!this._deleteUserCommandHandler) { this._deleteUserCommandHandler = new DeleteUserCommandHandler(this.userRepository); diff --git a/SerpentRace_Backend/src/Application/User/commands/ActivateUserCommand.ts b/SerpentRace_Backend/src/Application/User/commands/ActivateUserCommand.ts new file mode 100644 index 00000000..0cad88e6 --- /dev/null +++ b/SerpentRace_Backend/src/Application/User/commands/ActivateUserCommand.ts @@ -0,0 +1,3 @@ +export interface ActivateUserCommand { + id: string; +} diff --git a/SerpentRace_Backend/src/Application/User/commands/ActivateUserCommandHandler.ts b/SerpentRace_Backend/src/Application/User/commands/ActivateUserCommandHandler.ts new file mode 100644 index 00000000..b4a22ab0 --- /dev/null +++ b/SerpentRace_Backend/src/Application/User/commands/ActivateUserCommandHandler.ts @@ -0,0 +1,12 @@ +import { IUserRepository } from '../../../Domain/IRepository/IUserRepository'; +import { ActivateUserCommand } from './ActivateUserCommand'; + + +export class ActivateUserCommandHandler { + constructor(private readonly userRepo: IUserRepository) {} + + async execute(cmd: ActivateUserCommand): Promise { + await this.userRepo.activate(cmd.id); + return true; + } +} \ No newline at end of file diff --git a/SerpentRace_Backend/src/Application/User/commands/LogoutCommandHandler.ts b/SerpentRace_Backend/src/Application/User/commands/LogoutCommandHandler.ts index c6648076..ccbda81c 100644 --- a/SerpentRace_Backend/src/Application/User/commands/LogoutCommandHandler.ts +++ b/SerpentRace_Backend/src/Application/User/commands/LogoutCommandHandler.ts @@ -86,7 +86,7 @@ export class LogoutCommandHandler { // 5. Update user's last logout timestamp in database try { - const updateResult = await this.userRepo.update(userId, { updatedate: new Date() }); + const updateResult = await this.userRepo.update(userId, { updateDate: new Date() }); if (updateResult) { logAuth('User last logout timestamp updated', userId); } @@ -151,7 +151,7 @@ export class LogoutCommandHandler { } // Update user logout timestamp - await this.userRepo.update(userId, { updatedate: new Date() }); + await this.userRepo.update(userId, { updateDate: new Date() }); logAuth('User logged out from all devices', userId); return true; diff --git a/SerpentRace_Backend/src/Domain/Deck/DeckAggregate.ts b/SerpentRace_Backend/src/Domain/Deck/DeckAggregate.ts index 601fe7d8..21537dac 100644 --- a/SerpentRace_Backend/src/Domain/Deck/DeckAggregate.ts +++ b/SerpentRace_Backend/src/Domain/Deck/DeckAggregate.ts @@ -74,8 +74,8 @@ export class DeckAggregate { @Column({ type: 'int', default: CType.PUBLIC }) ctype!: CType; - @UpdateDateColumn({ name: 'update_date' }) - updatedate!: Date; + @UpdateDateColumn() + updateDate!: Date; @Column({ type: 'int', default: State.ACTIVE }) state!: State; diff --git a/SerpentRace_Backend/src/Domain/Game/GameAggregate.ts b/SerpentRace_Backend/src/Domain/Game/GameAggregate.ts index 0ad80db4..ece7aae6 100644 --- a/SerpentRace_Backend/src/Domain/Game/GameAggregate.ts +++ b/SerpentRace_Backend/src/Domain/Game/GameAggregate.ts @@ -86,8 +86,8 @@ export class GameAggregate { @Column({ type: 'timestamp', nullable: true, name: 'finishDate' }) enddate!: Date | null; - @UpdateDateColumn({ name: 'updateDate' }) - updatedate!: Date; + @UpdateDateColumn() + updateDate!: Date; } // Board Generation Types diff --git a/SerpentRace_Backend/src/Domain/IRepository/IUserRepository.ts b/SerpentRace_Backend/src/Domain/IRepository/IUserRepository.ts index cf64f295..4db923b0 100644 --- a/SerpentRace_Backend/src/Domain/IRepository/IUserRepository.ts +++ b/SerpentRace_Backend/src/Domain/IRepository/IUserRepository.ts @@ -7,4 +7,5 @@ export interface IUserRepository extends IPaginatedRepository; findByToken(token: string): Promise; deactivate(id: string): Promise; + activate(id: string): Promise; } diff --git a/SerpentRace_Backend/src/Domain/Organization/OrganizationAggregate.ts b/SerpentRace_Backend/src/Domain/Organization/OrganizationAggregate.ts index b6d63de8..5a3be365 100644 --- a/SerpentRace_Backend/src/Domain/Organization/OrganizationAggregate.ts +++ b/SerpentRace_Backend/src/Domain/Organization/OrganizationAggregate.ts @@ -35,8 +35,8 @@ export class OrganizationAggregate { @CreateDateColumn() regdate!: Date; - @UpdateDateColumn() - updatedate!: Date; + @UpdateDateColumn({ name: 'updateDate' }) + updateDate!: Date; @Column({ type: 'varchar', length: 500, nullable: true }) url!: string | null; diff --git a/SerpentRace_Backend/src/Domain/User/UserAggregate.ts b/SerpentRace_Backend/src/Domain/User/UserAggregate.ts index 60bab19c..86bd8b7d 100644 --- a/SerpentRace_Backend/src/Domain/User/UserAggregate.ts +++ b/SerpentRace_Backend/src/Domain/User/UserAggregate.ts @@ -51,7 +51,7 @@ export class UserAggregate { regdate!: Date; @UpdateDateColumn() - updatedate!: Date; + updateDate!: Date; @Column({ type: 'timestamp', nullable: true }) Orglogindate!: Date | null; diff --git a/SerpentRace_Backend/src/Infrastructure/Repository/DeckRepository.ts b/SerpentRace_Backend/src/Infrastructure/Repository/DeckRepository.ts index 9eb7594e..3c50b183 100644 --- a/SerpentRace_Backend/src/Infrastructure/Repository/DeckRepository.ts +++ b/SerpentRace_Backend/src/Infrastructure/Repository/DeckRepository.ts @@ -29,7 +29,7 @@ export class DeckRepository implements IDeckRepository { // Get paginated results const decks = await this.repo.find({ where: { state: Not(State.SOFT_DELETE) }, - order: { updatedate: 'DESC' }, + order: { updateDate: 'DESC' }, take: limit, skip: offset }); @@ -57,7 +57,7 @@ export class DeckRepository implements IDeckRepository { // Get paginated results const decks = await this.repo.find({ - order: { updatedate: 'DESC' }, + order: { updateDate: 'DESC' }, take: limit, skip: offset }); diff --git a/SerpentRace_Backend/src/Infrastructure/Repository/GameRepository.ts b/SerpentRace_Backend/src/Infrastructure/Repository/GameRepository.ts index 673b1901..b4832ee2 100644 --- a/SerpentRace_Backend/src/Infrastructure/Repository/GameRepository.ts +++ b/SerpentRace_Backend/src/Infrastructure/Repository/GameRepository.ts @@ -39,7 +39,7 @@ export class GameRepository implements IGameRepository { // Get paginated results const games = await this.repo.find({ where: { state: Not(GameState.CANCELLED) }, - order: { updatedate: 'DESC' }, + order: { updateDate: 'DESC' }, take: limit, skip: offset }); @@ -67,7 +67,7 @@ export class GameRepository implements IGameRepository { // Get paginated results (including deleted) const games = await this.repo.find({ - order: { updatedate: 'DESC' }, + order: { updateDate: 'DESC' }, take: limit, skip: offset }); @@ -153,7 +153,7 @@ export class GameRepository implements IGameRepository { queryBuilder.skip(offset); } - const games = await queryBuilder.orderBy('game.updatedate', 'DESC').getMany(); + const games = await queryBuilder.orderBy('game.updateDate', 'DESC').getMany(); const endTime = performance.now(); logDatabase('Game search completed', `executionTime: ${Math.round(endTime - startTime)}ms, query: ${query}, found: ${games.length}, total: ${totalCount}`); @@ -184,7 +184,7 @@ export class GameRepository implements IGameRepository { queryBuilder.skip(offset); } - const games = await queryBuilder.orderBy('game.updatedate', 'DESC').getMany(); + const games = await queryBuilder.orderBy('game.updateDate', 'DESC').getMany(); const endTime = performance.now(); logDatabase('Game search (including deleted) completed', `executionTime: ${Math.round(endTime - startTime)}ms, query: ${query}, found: ${games.length}, total: ${totalCount}`); @@ -251,7 +251,7 @@ export class GameRepository implements IGameRepository { try { const games = await this.repo.find({ where: { state: GameState.ACTIVE }, - order: { updatedate: 'DESC' } + order: { updateDate: 'DESC' } }); const endTime = performance.now(); logDatabase('Active games query completed', `executionTime: ${Math.round(endTime - startTime)}ms, found: ${games.length}`); @@ -270,7 +270,7 @@ export class GameRepository implements IGameRepository { const queryBuilder = this.repo.createQueryBuilder('game') .where('game.state != :cancelledState', { cancelledState: GameState.CANCELLED }) .andWhere('JSON_CONTAINS(game.players, :playerId)', { playerId: `"${playerId}"` }) - .orderBy('game.updatedate', 'DESC'); + .orderBy('game.updateDate', 'DESC'); const games = await queryBuilder.getMany(); const endTime = performance.now(); diff --git a/SerpentRace_Backend/src/Infrastructure/Repository/UserRepository.ts b/SerpentRace_Backend/src/Infrastructure/Repository/UserRepository.ts index 3563e993..40d772ae 100644 --- a/SerpentRace_Backend/src/Infrastructure/Repository/UserRepository.ts +++ b/SerpentRace_Backend/src/Infrastructure/Repository/UserRepository.ts @@ -345,5 +345,25 @@ export class UserRepository implements IUserRepository { } } + async activate(id: string) { + const startTime = Date.now(); + try { + await this.repo.update(id, { state: UserState.VERIFIED_REGULAR }); + const result = await this.findById(id); + logDatabase('User activated successfully', `update(${id}, { state: VERIFIED_REGULAR })`, Date.now() - startTime, { + userId: id, + success: !!result + }); + return result; + } + catch (error) { + logError('UserRepository.activate error', error as Error); + // Handle invalid UUID format + if (error instanceof Error && error.message.includes('invalid input syntax for type uuid')) { + throw new Error('Invalid user ID format'); + } + throw new Error('Failed to activate user in database'); + } + } } diff --git a/SerpentRace_Docker/sql_schema_only.sql b/SerpentRace_Docker/sql_schema_only.sql index f915bc4e..4cc18c87 100644 --- a/SerpentRace_Docker/sql_schema_only.sql +++ b/SerpentRace_Docker/sql_schema_only.sql @@ -19,7 +19,7 @@ CREATE TABLE "Users" ( "phone" VARCHAR(20) NULL, "state" INTEGER NOT NULL DEFAULT 0, "regdate" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updatedate" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updateDate" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, "Orglogindate" TIMESTAMP NULL ); @@ -33,7 +33,7 @@ CREATE TABLE "Organizations" ( "contactemail" VARCHAR(255) NOT NULL, "state" INTEGER NOT NULL DEFAULT 0, "regdate" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updatedate" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updateDate" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, "url" VARCHAR(500) NULL, "userinorg" INTEGER NOT NULL DEFAULT 0, "maxOrganizationalDecks" INTEGER NULL @@ -49,7 +49,7 @@ CREATE TABLE "Decks" ( "cards" JSONB NOT NULL DEFAULT '[]', "played_number" INTEGER NOT NULL DEFAULT 0, "ctype" INTEGER NOT NULL DEFAULT 0, - "update_date" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updateDate" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, "state" INTEGER NOT NULL DEFAULT 0, "organization_id" UUID NULL ); @@ -174,40 +174,6 @@ CREATE INDEX "IDX_Games_State" ON "Games" ("state"); CREATE INDEX "IDX_Games_CreatedBy" ON "Games" ("createdBy"); CREATE INDEX "IDX_Games_OrganizationId" ON "Games" ("organizationid"); --- Create update trigger for update_date columns -CREATE OR REPLACE FUNCTION update_updatedate_column() -RETURNS TRIGGER AS $$ -BEGIN - NEW.update_date = CURRENT_TIMESTAMP; - RETURN NEW; -END; -$$ language 'plpgsql'; - --- Apply update triggers -CREATE TRIGGER update_users_updatedate - BEFORE UPDATE ON "Users" - FOR EACH ROW EXECUTE FUNCTION update_updatedate_column(); - -CREATE TRIGGER update_organizations_updatedate - BEFORE UPDATE ON "Organizations" - FOR EACH ROW EXECUTE FUNCTION update_updatedate_column(); - -CREATE TRIGGER update_decks_updatedate - BEFORE UPDATE ON "Decks" - FOR EACH ROW EXECUTE FUNCTION update_updatedate_column(); - -CREATE TRIGGER update_chats_updatedate - BEFORE UPDATE ON "Chats" - FOR EACH ROW EXECUTE FUNCTION update_updatedate_column(); - -CREATE TRIGGER update_contacts_updatedate - BEFORE UPDATE ON "Contacts" - FOR EACH ROW EXECUTE FUNCTION update_updatedate_column(); - -CREATE TRIGGER update_games_updatedate - BEFORE UPDATE ON "Games" - FOR EACH ROW EXECUTE FUNCTION update_updatedate_column(); - -- Comments for documentation COMMENT ON TABLE "Users" IS 'User accounts with authentication and profile information'; COMMENT ON TABLE "Organizations" IS 'Organizations that can have multiple users and premium features'; diff --git a/SerpentRace_Frontend/src/App.jsx b/SerpentRace_Frontend/src/App.jsx index e82ae4ea..80aa0a79 100644 --- a/SerpentRace_Frontend/src/App.jsx +++ b/SerpentRace_Frontend/src/App.jsx @@ -19,8 +19,6 @@ import ProfileCard from "./components/Userdetails/Userdetails" import { ToastConfig } from "./components/Toastify/toastifyServices" // ✅ fontos: named import, nem default! import VerifyEmailPage from "./pages/Auth/VerifyEmailPage" - - function App() { const [isMobile, setIsMobile] = useState(false) @@ -66,7 +64,7 @@ function App() { } /> } /> } /> - } /> + {/* } /> */} } /> diff --git a/SerpentRace_Frontend/src/components/Footer/Footer.jsx b/SerpentRace_Frontend/src/components/Footer/Footer.jsx index 2c04d798..3a742156 100644 --- a/SerpentRace_Frontend/src/components/Footer/Footer.jsx +++ b/SerpentRace_Frontend/src/components/Footer/Footer.jsx @@ -70,12 +70,6 @@ const Footer = () => { > Rólunk - {/* Közösség */} diff --git a/SerpentRace_Frontend/src/components/Landingpage/LandingPage.jsx b/SerpentRace_Frontend/src/components/Landingpage/LandingPage.jsx index 79391347..5124ed65 100644 --- a/SerpentRace_Frontend/src/components/Landingpage/LandingPage.jsx +++ b/SerpentRace_Frontend/src/components/Landingpage/LandingPage.jsx @@ -7,10 +7,12 @@ import { FaUsers, FaPaintBrush, FaHeadset } from "react-icons/fa" import { motion } from "framer-motion" import { isAuthenticated } from "../../hooks/useRequireAuth" // <-- added import import { useNavigate } from "react-router-dom" // <-- NEW +import HandleNavigate from "../../utils/HandleNavigate/HandleNavigate" // <-- NEW -const LandingPage = ({ onNavigateToPlay, onNavigateToAuth, onNavigateToGame, onNavigateToContacts }) => { - const auth = isAuthenticated() // <-- check without redirect - const navigate = useNavigate() // <-- NEW +// 🔧 HIBA JAVÍTVA: függvénydefiníció hozzáadva +const LandingPage = () => { + const { goLanding, goAbout, goHome, goLogin, goAuth } = HandleNavigate() + const auth = isAuthenticated() // a hitelesítési állapot meghatározásához return (
@@ -45,6 +47,7 @@ const LandingPage = ({ onNavigateToPlay, onNavigateToAuth, onNavigateToGame, onN A SerpentRace egy társasjáték, ahol új barátokra lelhetsz, közösséget építhetsz és tanulhatsz – mindezt szórakozva! + - - - + + + ) : ( - + )}
@@ -178,7 +181,7 @@ const LandingPage = ({ onNavigateToPlay, onNavigateToAuth, onNavigateToGame, onN diff --git a/SerpentRace_Frontend/src/components/Navbar/Navbar.jsx b/SerpentRace_Frontend/src/components/Navbar/Navbar.jsx index 738bd17b..a1af7983 100644 --- a/SerpentRace_Frontend/src/components/Navbar/Navbar.jsx +++ b/SerpentRace_Frontend/src/components/Navbar/Navbar.jsx @@ -1,18 +1,17 @@ import React, { useState } from "react" import Logo from "../../assets/pictures/Logo" import { Link } from "react-router-dom" -import HandleNavigate from "../../utils/HandleNavigate/HandleNavigate"// ✅ importáld a navigációs hookot +import HandleNavigate from "../../utils/HandleNavigate/HandleNavigate" // ✅ importáld a navigációs hookot +import { FaSignOutAlt, FaChartBar, FaUser, FaBars } from "react-icons/fa" -const navLinkClass = - "px-3 py-2 rounded-lg text-white transition-all duration-200 hover:bg-white/10" +const navLinkClass = "px-3 py-2 rounded-lg text-white transition-all duration-200 hover:bg-white/10" const navLinkClassPlay = "px-4 py-2 rounded-lg text-white bg-white/12 hover:bg-white/20 transition-all duration-200" const Navbar = () => { const [menuOpen, setMenuOpen] = useState(false) - const isLoggedIn = Boolean( - localStorage.getItem("authLevel") && localStorage.getItem("username") - ) + const [userMenuOpen, setUserMenuOpen] = useState(false) + const isLoggedIn = Boolean(localStorage.getItem("authLevel") && localStorage.getItem("username")) // ✅ Használjuk a HandleNavigate hookot const { goLanding, goAbout, goHome, goLogin, goContacts } = HandleNavigate() @@ -25,16 +24,23 @@ const Navbar = () => { return (