Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
ec0d487
Initial commit
kotru21 Aug 13, 2025
1185c41
Initialize React TypeScript Vite project
kotru21 Aug 13, 2025
2f976f4
theme fix
kotru21 Aug 13, 2025
62e1560
Add ExpandableText component and integrate in pages
kotru21 Aug 13, 2025
371858d
Optimize UI components with React memoization
kotru21 Aug 13, 2025
f0dba60
Improve registration validation and error handling
kotru21 Aug 13, 2025
37e8fa9
Refactor UI into presentational components
kotru21 Aug 14, 2025
6c8f4f6
Refactor pagination types to shared module
kotru21 Aug 14, 2025
13a0e3f
Update types.ts
kotru21 Aug 14, 2025
4f830e1
Add snippets to homepage and implement snippet details page
kotru21 Aug 15, 2025
ca0778a
Add account page and refactor card views
kotru21 Aug 15, 2025
bb37b36
Preserve mode in navigation and back links
kotru21 Aug 15, 2025
817be37
Add Skeleton loading component and integrate in UI
kotru21 Aug 15, 2025
6ab2de5
Update answer and comment form layout on pages
kotru21 Aug 15, 2025
7994e80
Make header sticky and adjust padding on scroll
kotru21 Aug 15, 2025
64d1288
Add Avatar component and integrate in user views
kotru21 Aug 15, 2025
831a0ce
Refactor header, question, and snippet UI components
kotru21 Aug 15, 2025
43b03a5
Add create page, socket support, and unify card views
kotru21 Aug 17, 2025
048dbb9
Add debug logging and owner checks to QuestionPage
kotru21 Aug 17, 2025
a79f34b
Remove debug logging and flags from auth and question modules
kotru21 Aug 17, 2025
c29a220
Improve AnswerItemView styling and correct label
kotru21 Aug 17, 2025
0350536
Improve header scroll behavior and UI links
kotru21 Aug 17, 2025
e1032fd
websocket
kotru21 Aug 22, 2025
89e5196
Add real-time updates for question answers via socket
kotru21 Aug 24, 2025
0e1afbb
Simplify question owner detection logic
kotru21 Aug 24, 2025
45f9dc5
Refactor form logic into reusable hooks
kotru21 Aug 24, 2025
46c2ba2
Implement path aliasing and refactor imports
kotru21 Aug 24, 2025
c8940f5
Add MyItemsPage and navigation link
kotru21 Aug 24, 2025
efcbfeb
Add edit and delete functionality for questions and snippets
kotru21 Aug 24, 2025
6d93e81
Add edit and delete functionality for answers and comments
kotru21 Aug 24, 2025
19e39e9
Refactor item details and unify UI buttons
kotru21 Aug 24, 2025
ce45dba
Refactor auth token handling and improve answer form UX
kotru21 Aug 24, 2025
b990184
Refactor item details structure and imports
kotru21 Aug 24, 2025
f3b9f21
Add real-time update/delete for answers and comments
kotru21 Aug 24, 2025
32d556d
Add centralized notifications and error handling
kotru21 Aug 27, 2025
3eec5cf
Add resolved status indicator to question cards
kotru21 Aug 27, 2025
eb773bd
Optimize rendering with memoization in item components
kotru21 Aug 27, 2025
d07acea
Readme
kotru21 Aug 27, 2025
7babd26
Add feature screenshots to README files
kotru21 Aug 27, 2025
0b466e8
Update package-lock.json
kotru21 Aug 27, 2025
91acb0a
Merge branch 'main' into dev
elvisduru Sep 8, 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
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto
24 changes: 24 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
197 changes: 197 additions & 0 deletions README.en.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
# StackOverflow Clone (Frontend + WebSocket Relay)

[Русский](./README.md) | English

Modern educational single page application (StackOverflow‑like domain):
questions with answers, code snippets with likes/dislikes and comments, user account management, real‑time updates via Socket.IO.

> NOTE: For real‑time features you MUST run the separate WebSocket relay server located in `websocket-server` (see "Running the WebSocket server"). Without it the UI works, but no live events (comments / answers / status changes) will arrive.

## Backend / API

Production REST API base URL: <https://codelang.vercel.app>

API documentation (Swagger / OpenAPI): <https://codelang.vercel.app/docs>

Locally the frontend uses a Vite proxy mapping `/api` → `https://codelang.vercel.app` (see `vite.config.ts`). Override `VITE_API_BASE_URL` if you need a different backend.

## Features

- Authentication (login / logout / register) with session persistence (cookies, `withCredentials`).
- Questions: create, edit, delete, answers, mark/unmark answer correctness, live updates of answers and their states.
<img src="./readme/localhost_5173__mode=questions.png">
- Snippets: create, edit, delete, like / dislike, comments, live comment updates.
<img src="./readme/localhost_5173__mode=snippets.png">
- Infinite pagination (`useInfiniteQuery`).
- Optimistic updates + subsequent cache validation (React Query invalidation).
- Toast‑like notifications via a lightweight window event emitter.
- Theming (light / dark) with user preference persistence and system preference fallback.
<img src="./readme/localhost_5173__mode=questions (2).png">
- Code editor / viewer (CodeMirror + Prism highlight).
<img src="./readme/localhost_5173__code_editor.png">
- Type‑safe forms (`react-hook-form` + `zod`).
- Path alias imports (`@`, `@/shared`, etc.) configured in Vite.

## Tech Stack

Frontend:

- React 19 + TypeScript
- Vite 7 (fast build, HMR, mkcert for local https)
- React Router v7
- TanStack React Query (data / cache / synchronization)
- Socket.IO client (real‑time)
- Tailwind CSS 4
- Axios (HTTP)
- React Hook Form + Zod (validation)
- CodeMirror / Prism (editor & syntax highlighting)

WebSocket relay server (`/websocket-server`):

- Node.js + TypeScript
- socket.io (server)
- Simple event relay (comments & answers) without direct REST API access.

## Architectural Overview

Feature / slice inspired layout:

- `src/app` — context providers (auth, theme, notifications), top‑level layout pieces.
- `src/entities` — domain entities (question, snippet, user): types, API hooks, business hooks.
- `src/pages` — route pages & view compositions.
- `src/shared` — shared utilities: HTTP client, normalization, socket, notifications, UI components, forms, language service.
- `websocket-server` — standalone Socket.IO relay.

Data fetching & mutations are encapsulated in hooks (`useQuestion`, `useCreateAnswer`, `useSnippets`, etc.). Real‑time subscriptions are separate hooks (`useSnippetComments`, `useQuestionAnswers`). Socket events update the React Query cache (`setQueryData`) and then optionally trigger `invalidateQueries` to reconcile with backend truth.

## Real‑time Events

Comment (snippet room `snippet:{id}`):

- `comment:created`, `comment:updated`, `comment:deleted`.

Answer (question room `question:{id}`):

- `answer:created`, `answer:state_changed`, `answer:updated`, `answer:deleted`.

Client first persists via REST, then (for responsiveness) may emit an event (optimistic relay) which is later confirmed by cache invalidation.

## Environment Variables (Vite)

Use `.env.local` (do not commit) if you need overrides:

```bash
VITE_API_BASE_URL=/api # Default /api (proxied via vite.config)
VITE_SOCKET_URL=http://localhost:4000 # WebSocket relay URL (dev)
VITE_SOCKET_PATH=/socket.io # Optional, auto‑derived when omitted
```

If the API backend is separate (no Vite proxy), set full origin:

```bash
VITE_API_BASE_URL=https://api.example.com
```

## Quick Start (Frontend)

1. Install dependencies:

```powershell
npm install
```

1. (Optional) create `.env.local` to override API / Socket.

1. Run dev server:

```powershell
npm run dev
```

1. Open <https://localhost:5173>. (mkcert produces a local cert; add a browser exception if warned.)

## Running the WebSocket Server

Enter the subfolder and install separately:

```powershell
cd .\websocket-server
npm install
npm run dev # starts on port 4000
```

You should see: `Socket.io server started on ws://localhost:4000`.

Ensure the frontend can reach it (default `VITE_SOCKET_URL=http://localhost:4000`).

## Build & Preview

```powershell
npm run build # tsc -b + vite build
npm run preview # local static preview
```

Production bundle is emitted to `dist`.

## Scripts

- `npm run dev` — Vite dev server (https + HMR)
- `npm run build` — type check (project refs) + build
- `npm run preview` — preview built SPA
- `npm run lint` — ESLint

## HTTP Client & Auth

`src/shared/api/http.ts` configures Axios with `baseURL = VITE_API_BASE_URL || /api`, `withCredentials: true`. A 401 interceptor redirects to `/login?from=...` for protected pages.

## Caching Strategy

React Query:

- Lists (`useInfiniteQuery`) key pattern: `['questions', { search, sortBy }]`.
- Details: `['question', id]`, `['snippet', id]`.
- Post-mutation targeted invalidation.
- Real‑time events first patch cache (`setQueryData`), then optionally reconcile using `invalidateQueries`.

## Theming

`ThemeProvider` sets `data-theme` and toggles `dark` class on `html` & `body`, persisting selection in `localStorage` (values: `light | dark`).

## Notifications

`src/shared/notifications.ts` provides a tiny CustomEvent bus. Hooks dispatch success / error messages (auto TTL).

## Adding a New Entity (Pattern)

1. Create `src/entities/<entity>`: `types.ts`, `api.ts`, `hooks/`.
2. Define types + normalization adapter.
3. Implement hooks: list (`use<Entity>s`), detail (`use<Entity>`), mutations via `useApiMutation`.
4. Add socket subscription hook if needed (model after `useSnippetComments` / `useQuestionAnswers`).

## Real‑time Integration Details

File `src/shared/socket.ts`:

- Lazy client initialization.
- Env driven config (`VITE_SOCKET_URL`, `VITE_SOCKET_PATH`).
- Forced WebSocket transport.
- Verbose dev logging of connect / errors.

## Codebase Style

- Type‑first: domain types in `entities/*/types.ts`.
- Manual lightweight normalization (coercion, counts for likes/dislikes, etc.).
- Avoid unnecessary rerenders: structured query keys, limited retries, disabled `refetchOnWindowFocus` for list views.

## Quality Gate

Before committing:

```powershell
npm run lint
npm run build
```

---

See Russian version in `README.md` for original description or open an issue for questions.
Loading