# Frontend Kódolási Útmutató - SerpentRace ## Tartalomjegyzék 1. [Navigáció és Routing](#navigáció-és-routing) 2. [Fájl és Mappa Struktúra](#fájl-és-mappa-struktúra) 3. [Komponens Konvenciók](#komponens-konvenciók) 4. [State Management](#state-management) 5. [API Hívások](#api-hívások) 6. [Hibakezelés](#hibakezelés) 7. [Elnevezési Konvenciók](#elnevezési-konvenciók) --- ## Navigáció és Routing ### ✅ Helyes gyakorlat: HandleNavigate használata **MINDIG használd a központosított HandleNavigate hook-ot navigációhoz:** ```jsx import HandleNavigate from "../../utils/HandleNavigate/HandleNavigate" const MyComponent = () => { const { goHome, goLogin, goDeckDetails } = HandleNavigate() const handleClick = () => { goHome() // Egyszerű navigáció } const handleDeckView = (deckId) => { goDeckDetails(deckId) // Dinamikus route paraméterrel } const handleLobby = (gameCode) => { goLobby({ gameCode }) // State passzolással } } ``` ### ❌ Kerülendő: Direkt useNavigate használat ```jsx // SOHA NE HASZNÁLD EZT! import { useNavigate } from "react-router-dom" const MyComponent = () => { const navigate = useNavigate() navigate("/home") // ❌ NEM JÓ! } ``` ### Elérhető Navigációs Függvények **HandleNavigate által biztosított függvények:** ```jsx const { // Általános goTo, // goTo('/any-path', { state: {...} }) goBack, // Vissza az előző oldalra // Authentikáció goHome, // → /home goLogin, // → /login, state: { success, message } goRegister, // → /register (alias: goAuth) goLanding, // → / (landing page) // Deck Management goDecks, // → /decks goDeckDetails, // goDeckDetails(deckId) → /deck/:deckId goDeckCreator, // → /deck-creator goDeckCreatorEdit, // goDeckCreatorEdit(deckId) → /deck-creator/:deckId // Game Flow goLobby, // goLobby({ gameCode }) → /lobby goChooseDeck, // goChooseDeck({ username, deckIds }) → /choosedeck goPlayerSetup, // goPlayerSetup({ deckIds }) → /player-setup goGame, // goGame({ players, gameState }) → /game // Egyéb goContacts // → /contacts (alias: goCompanies) } = HandleNavigate() ``` ### Route Konstansok **Használd a centralizált route konstansokat:** ```jsx // src/utils/routes.js import { ROUTES } from '../../utils/routes' // App.jsx-ben } /> } /> // ❌ NE használj string literálokat: } /> // NEM JÓ! ``` ### State Passzolás **Így adj át adatokat navigáció során:** ```jsx // Régi mód (useNavigate) - ❌ NE! navigate('/lobby', { state: { gameCode: 'ABC123' } }) // Új mód (HandleNavigate) - ✅ JÓ! goLobby({ gameCode: 'ABC123' }) // Fogadó oldalon: import { useLocation } from 'react-router-dom' const Lobby = () => { const location = useLocation() const gameCode = location.state?.gameCode } ``` --- ## Fájl és Mappa Struktúra ### Mappa Szervezés ``` src/ ├── api/ # API hívások │ ├── userApi.js │ ├── deckApi.js │ └── gameApi.js ├── assets/ # Statikus fájlok │ ├── backgrounds/ │ ├── images/ │ └── icons/ ├── components/ # Újrahasználható komponensek │ ├── Buttons/ │ ├── Inputs/ │ ├── Navbar/ │ └── PopUp/ ├── hooks/ # Custom Hooks │ └── useRequireAuth.jsx ├── pages/ # Oldal komponensek │ ├── Auth/ │ ├── Game/ │ ├── Decks/ │ └── Landing/ ├── utils/ # Utility függvények │ ├── HandleNavigate/ │ └── routes.js └── App.jsx # Fő alkalmazás komponens ``` ### Fájl Elnevezési Konvenciók - **Komponensek**: PascalCase - `LoginForm.jsx`, `DeckCreator.jsx`, `ButtonGreen.jsx` - **Utility fájlok**: camelCase - `routes.js`, `randomUtils.js`, `userApi.js` - **Hook fájlok**: camelCase, "use" prefix - `useRequireAuth.jsx`, `useLocalStorage.jsx` --- ## Komponens Konvenciók ### Funkcionális Komponens Sablon ```jsx import React, { useState, useEffect } from 'react' import HandleNavigate from '../../utils/HandleNavigate/HandleNavigate' /** * Komponens rövid leírása * @returns {JSX.Element} */ const MyComponent = () => { // 1. Hooks (HandleNavigate, useState, useEffect, stb.) const { goHome } = HandleNavigate() const [data, setData] = useState(null) // 2. Effect hooks useEffect(() => { // Component mount logic }, []) // 3. Event handlers const handleClick = () => { // Logic } // 4. Render return (
{/* JSX */}
) } export default MyComponent ``` ### Import Sorrend ```jsx // 1. React és third-party library-k import React, { useState } from 'react' import { motion } from 'framer-motion' // 2. React Router hooks (useLocation, useParams - NEM useNavigate!) import { useLocation } from 'react-router-dom' // 3. Custom hooks és utils import HandleNavigate from '../../utils/HandleNavigate/HandleNavigate' import useRequireAuth from '../../hooks/useRequireAuth' // 4. API import { getUserData } from '../../api/userApi' // 5. Komponensek import Button from '../../components/Buttons/Button' import Navbar from '../../components/Navbar/Navbar' // 6. Assets import Background from '../../assets/backgrounds/Background' ``` --- ## State Management ### Local State ```jsx // Egyszerű state const [count, setCount] = useState(0) // Object state const [user, setUser] = useState({ name: '', email: '' }) // Array state const [items, setItems] = useState([]) ``` ### LocalStorage Használat **useRequireAuth hook használata auth kezeléshez:** ```jsx import useRequireAuth from '../../hooks/useRequireAuth' const MyComponent = () => { const [username] = useRequireAuth({ key: 'username', redirectTo: '/login' }) // username automatikusan szinkronizálva van localStorage-el // Ha nincs username, automatikus redirect /login-re } ``` **Manuális localStorage:** ```jsx // Írás localStorage.setItem('gameToken', token) // Olvasás const token = localStorage.getItem('gameToken') // Törlés localStorage.removeItem('gameToken') ``` --- ## API Hívások ### API File Struktúra **Minden API endpoint egy külön file-ban (`userApi.js`, `deckApi.js`, `gameApi.js`):** ```jsx // src/api/userApi.js import axiosInstance from './axiosInstance' export const getUserData = async (userId) => { try { const response = await axiosInstance.get(`/users/${userId}`) return response.data } catch (error) { console.error('Error fetching user data:', error) throw error } } export const updateUser = async (userId, userData) => { try { const response = await axiosInstance.put(`/users/${userId}`, userData) return response.data } catch (error) { console.error('Error updating user:', error) throw error } } ``` ### API Hívás Komponensben ```jsx import { getUserData } from '../../api/userApi' const MyComponent = () => { const [loading, setLoading] = useState(false) const [error, setError] = useState(null) const [data, setData] = useState(null) const fetchData = async () => { setLoading(true) setError(null) try { const result = await getUserData(userId) setData(result) } catch (err) { setError(err.message || 'Hiba történt') } finally { setLoading(false) } } useEffect(() => { fetchData() }, [userId]) if (loading) return
Betöltés...
if (error) return
Hiba: {error}
return
{/* data megjelenítése */}
} ``` --- ## Hibakezelés ### Try-Catch Blokkok ```jsx const handleSubmit = async () => { try { const response = await createDeck(deckData) // Siker kezelése notifySuccess('Deck sikeresen létrehozva!') goDecks() } catch (error) { // Hiba kezelése const errorMessage = error.response?.data?.message || 'Ismeretlen hiba' setError(errorMessage) notifyError(errorMessage) } } ``` ### Toast Notifications ```jsx import { notifySuccess, notifyError } from '../../components/Toastify/toastifyServices' // Siker üzenet notifySuccess('✅ Művelet sikeres!') // Hiba üzenet notifyError('❌ Hiba történt!') // Egyedi konfiguráció notifySuccess('Mentve!', { autoClose: 2000 }) ``` --- ## Elnevezési Konvenciók ### JavaScript/React | Típus | Konvenció | Példa | |-------|-----------|-------| | Komponensek | PascalCase | `LoginForm`, `DeckCreator` | | Függvények | camelCase | `handleClick`, `fetchUserData` | | Változók | camelCase | `userName`, `isLoading` | | Konstansok | UPPER_SNAKE_CASE | `API_BASE_URL`, `MAX_PLAYERS` | | Private változók | _camelCase | `_internalState` | | Event handlers | handle + PascalCase | `handleSubmit`, `handleInputChange` | | Boolean változók | is/has/can prefix | `isLoading`, `hasError`, `canEdit` | ### CSS Classes (Tailwind) ```jsx // Használj explicit class neveket
// Kerüld a túl hosszú class stringeket - bontsd több sorra
``` ### Fájl Nevek - **Egyedi komponens**: `LoginForm.jsx` (nem `login-form.jsx`) - **Index fájlok**: `index.jsx` (ha könyvtárban több file van) - **Utility fájlok**: `randomUtils.js` (camelCase) - **API fájlok**: `userApi.js` (camelCase + Api postfix) --- ## Teljes Példa - Best Practices ```jsx // src/pages/Example/ExamplePage.jsx import React, { useState, useEffect } from 'react' import { useLocation } from 'react-router-dom' import { motion } from 'framer-motion' import HandleNavigate from '../../utils/HandleNavigate/HandleNavigate' import useRequireAuth from '../../hooks/useRequireAuth' import { fetchExampleData, updateExampleData } from '../../api/exampleApi' import { notifySuccess, notifyError } from '../../components/Toastify/toastifyServices' import Navbar from '../../components/Navbar/Navbar' import Button from '../../components/Buttons/Button' import Background from '../../assets/backgrounds/Background' /** * Example Page - Komponens rövid leírása * @returns {JSX.Element} */ const ExamplePage = () => { // 1. Auth & Navigation const [username] = useRequireAuth({ key: 'username', redirectTo: '/login' }) const { goHome, goBack } = HandleNavigate() const location = useLocation() // 2. State const [data, setData] = useState(null) const [loading, setLoading] = useState(false) const [error, setError] = useState(null) // 3. Effects useEffect(() => { loadData() }, []) // 4. Functions const loadData = async () => { setLoading(true) setError(null) try { const result = await fetchExampleData() setData(result) } catch (err) { const errorMsg = err.response?.data?.message || 'Hiba történt' setError(errorMsg) notifyError(errorMsg) } finally { setLoading(false) } } const handleSave = async () => { try { await updateExampleData(data) notifySuccess('✅ Sikeresen mentve!') goHome() } catch (err) { notifyError('❌ Mentés sikertelen') } } const handleCancel = () => { goBack() } // 5. Conditional Rendering if (loading) { return (
Betöltés...
) } if (error) { return (
Hiba: {error}
) } // 6. Main Render return (

Example Page

{/* Content */}
{data && (
{/* Render data */}
)}
{/* Actions */}
) } export default ExamplePage ``` --- ## Összefoglalás - Legfontosabb Szabályok 1. ✅ **MINDIG használd HandleNavigate-et** navigációhoz 2. ✅ **Használd a ROUTES konstansokat** az App.jsx-ben 3. ✅ **API hívások külön file-okban** (userApi.js, deckApi.js, stb.) 4. ✅ **Try-catch minden async műveletnél** 5. ✅ **Toast notifications** a felhasználói visszajelzéshez 6. ✅ **useRequireAuth hook** auth védett oldalaknál 7. ✅ **Konzisztens import sorrend** 8. ✅ **PascalCase komponenseknek, camelCase változóknak** 9. ❌ **SOHA ne használj useNavigate közvetlen** 10. ❌ **Ne használj string literal route-okat** --- **Verzió:** 1.0 **Utolsó frissítés:** 2025-01-17 **Készítette:** SerpentRace Development Team