Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions docs/.keep
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
placeholder
7 changes: 7 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Project Documentation

- Backend API: ./backend/API.md
- Frontend Components: ./frontend/components/COMPONENTS.md
- Frontend Services: ./frontend/services/SERVICES.md
- Frontend Utils: ./frontend/utils/UTILS.md
- Frontend Store: ./frontend/store/STORE.md
93 changes: 93 additions & 0 deletions docs/backend/API.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
## Base URL
- http://localhost:3030

## Authentication
- Some endpoints require JWT via Authorization header: `Bearer <token>`

## Users
- POST /api/users/register
- Body: { name, email, password, password2, language }
- 200: user data; 400/500: errors
- POST /api/users/login
- Body: { email, password }
- 200: { success: boolean, token: string }
- POST /api/users/user-language
- Body: { userEmail, userLanguage }
- 200 on success
- GET /api/users/get-user-language?email=string
- 200: language string
- POST /api/users/google-auth
- Body: { email, name, language, accessToken, imageUrl }
- 200: { success: boolean, token: string }

## Events
- POST /api/events/add-event
- Body: Event
- POST /api/events/delete-event
- Body: { id: number }
- POST /api/events/edit-event
- Body: Event
- GET /api/events/get-events
- 200: Event[]
- GET /api/events/get-event?id=number
- 200: Event

## Games
- GET /api/games/get-games
- 200: approved games array

## My Games (v1)
- POST /api/v1/my-games/delete-game
- Body: Game
- 200: Game[]
- POST /api/v1/my-games/edit-game
- Body: Game
- 200: Game[]
- POST /api/v1/my-games/add-game
- Body: Game (appToken added server-side)
- 200: Game
- GET /api/v1/my-games/get-games?userId=number
- 200: Game[]

## Statistic (v1)
- POST /api/v1/statistic/set-game-result
- Body: GameData[]
- Headers: Authorization: Bearer <appToken>
- 200 on success; 400/500 with error codes
- GET /api/v1/statistic/recent-games?userId=string
- JWT required
- 200: RecentGames[]
- GET /api/v1/statistic/most-popular-games
- JWT required
- 200: MostPopularGames[]
- GET /api/v1/statistic/best-users
- JWT required
- 200: BestUser[]
- GET /api/v1/statistic/statistic
- JWT required
- 200: MostPopularGames[]
- GET /api/v1/statistic/get-leaders?appName=string
- 200: Leaders[]

## User Settings (v1)
- POST /api/v1/user-settings/change-password
- JWT required
- Body: { oldPassword, newPassword, repeatNewPassword, userId }
- 200 on success or 400 with validation errors

## Types
- User, UserFieldsToRegister, Game, Event, GameData, ErrorBlock, etc. See `server/models` and `frontend/src/models.ts`.

## Examples
```bash
curl -X POST http://localhost:3030/api/users/register \
-H 'Content-Type: application/json' \
-d '{"name":"Ada","email":"ada@example.com","password":"secret123","password2":"secret123","language":"en"}'
```

```bash
curl -X POST http://localhost:3030/api/v1/statistic/set-game-result \
-H 'Authorization: Bearer APP_TOKEN' \
-H 'Content-Type: application/json' \
-d '[{"userToken":"u1","playedTime":120,"scores":100,"resultStatus":1,"participationStatus":1}]'
```
68 changes: 68 additions & 0 deletions docs/frontend/components/COMPONENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
## Components Overview
Re-exported from `frontend/src/components/index.ts`.

### ProtectedRoute
- Props: `ProtectedRouteProps` { status: AuthStatus; path: string; children }
- Usage:
```tsx
<ProtectedRoute status={AuthStatus.Authorized} path="/dashboard">
<Dashboard />
</ProtectedRoute>
```

### CaButton (Material UI wrapper)
- Props: inherits Material `ButtonProps`
- Usage:
```tsx
<CaButton color="primary" variant="raised">Save</CaButton>
```

### CaSnackbar
- Props: `CaSnackbarProps` { type: SnackbarType; transitionDirection; message; onClose?; ...SnackbarProps }
- Usage:
```tsx
<CaSnackbar open type={SnackbarType.Success} message="Saved" transitionDirection={transitionDirection.Up} />
```

### CaTable
- Props: `CaTableProps` { rowData: Row[]; columnDef: HeaderName[]; handleRowClick? }
- Usage:
```tsx
<CaTable rowData={rows} columnDef={columns} />
```

### CaSelect
- Props: `CaSelectProps` { values: string[]; displayedValues: string[]; currentValue: string; handleChange(evt, i18n) }
- Usage:
```tsx
<CaSelect values={["en","ru"]} displayedValues={["EN","RU"]} currentValue="en" handleChange={onChange} />
```

### AppMenu
- Props: `AppMenuProps` { appMenuItems: AppMenuItem[]; imageUrl?; children? }

### Spinner
- Props: `SpinnerProps` { isActive: boolean }

### GameCard
- Props: `GameCardProps` { game: GameModel; status: BattleStatus; battleStartTime: Date; moreMenuItems: MoreMenuItem[]; joinGame(id); leaveGame(id) }

### Charts
- CircleDiagram: `CircleDiagramProps` { diagramData: WinRateDiagramData }
- BarChart: `BarChartProps` { diagramData: WeekReportData[]; config: BarChartConfig }

### Forms
- LoginForm: `LoginFormProps` { status: AuthStatus; history; spinnerRun; loginUser(); socialNetworksLogin() }
- RegistrationForm: `RegistrationFormProps` { history; status; spinnerRun; language; registerUser() }
- ChangePasswordForm: `ChangePasswordFormProps` { user: FrontEndUser | undefined; changePasswordStatus: LoadStatus; submit(data) }
- GameForm: `GameFormProps` { userId; config: SettingFormType; model: GameForSettingForm; submit(GameModel) }
- AddGameComponent: `AddGameComponentProps` { authStatus; history; user; addGame(GameModel) }
- EditGameComponent: `EditGameComponentProps` { authStatus; history; user; games; match; editGame(GameModel) }

### Misc
- Navbar: `NavbarProps` { linksToRender?: Link[]; children? }
- Logo: `LogoProps` { text: string; onClick: () => void }
- VkDialog: `VkDialogProps` { apiId; open; onClose; onSuccess }
- Countdown: `CountdownProps` { time: number; onTimeChange? }
- Author: `AuthorProps` { author_name; author_picture }

22 changes: 22 additions & 0 deletions docs/frontend/services/SERVICES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
## Services

### HttpWrapper
Location: `frontend/src/services/axiosWrapper.service.ts`
- Base URL: `${schema}://${host}:${port}/` from `frontend/src/config.json`
- Methods:
- `post<T, R>(url: string, data: T): Promise<AxiosResponse<R>>`
- `get<R>(url: string): Promise<AxiosResponse<R>>`
- Example:
```ts
await HttpWrapper.post('api/users/login', { email, password });
```

### ChartsService
Location: `frontend/src/services/charts.service.ts`
- `getWinRateData(gameName: string, gameData: RecentGames[]): WinRateDiagramData`
- `getWeekReportData(gameName: string, historyOfUserGames: RecentGames[]): WeekReportData[]`
- Example:
```ts
const pieData = ChartsService.getWinRateData('Chess', recentGames);
const weekData = ChartsService.getWeekReportData('Chess', recentGames);
```
38 changes: 38 additions & 0 deletions docs/frontend/store/STORE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
## Redux Store
Location: `frontend/src/store`

### AppState
Defined in `store.config.ts`:
- `auth: AuthState`
- `games: GamesState`
- `statistic: StatisticState`
- `socket: SocketState`
- `snackbarUi: SnackbarUiState`
- `restorePassword: RestorePasswordState`
- `userSettings: UserSettingsState`
- `myGames: MyGamesState`
- `room: RoomState`

### Actions (selected)
- Auth: `RegisterUser`, `LoginUser`, `LogoutUser`, `SetCurrentUser`, `SocialNetworksLogin`
- Games: `LoadGames`, `LoadGamesSuccess`, `LoadGamesError`
- Events: `AddEvent`, `DeleteEvent`, `EditEvent`, `LoadEvents`, `LoadEvent`
- MyGames: `AddGame`, `EditGame`, `DeleteGame`, `InitMyGames`, `LoadMyGamesSuccess`
- Statistic: `InitBestUsers`, `InitMostPopularGames`, `InitRecentGames(userToken)`, `InitLeaders(appName)`
- RestorePassword: `SendRestoreRequest(email)`, `ResetRequest`
- Room: `SetRooms`, `SetPlayerRoom`, `JoinRoom`, `LeaveRoom`, `NotifyCountdown`
- Socket: `InitEvents(games)`, `EmitEvent(name)`, `EmitEventWithOptions({ eventName, options })`, `CloseSocket`

### Effects (Epics)
See `*.effects.ts` files in each module. Root epic combines all.

### Usage
```ts
import { connect } from 'store';
import { LoadGames } from 'store/games';

const mapState = (state: AppState) => ({ games: state.games });
const mapDispatch = (dispatch) => ({ load: () => dispatch(new LoadGames()) });

export default connect(mapState)(Component);
```
27 changes: 27 additions & 0 deletions docs/frontend/utils/UTILS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
## Utils

### history
- `history`: Hash history instance

### setAuthToken / deleteAuthToken
- `setAuthToken(token: string)`: sets Axios default Authorization header
- `deleteAuthToken()`: removes Axios default Authorization header

### isEmpty
- Generic check for empty values, empty objects, or whitespace strings

### getLanguage
- `getCurrentLanguage(i18n: i18n): string`
- `getCurrentLanguageFromLocalStorage(): string`

### i18nInstance
- Initialized i18n with `en` and `ru` locales

### isObjectsEqual
- Shallow equality by own properties

### Omit
- Type helper: `Omit<T, K extends keyof T>`

### translateNumberOfWeekToItsName
- Converts `DaysOfWeek` number to weekday name