add hub menagment functions

This commit is contained in:
gitGnome
2026-04-29 14:46:22 +02:00
parent 221fb47495
commit 6378966267
19 changed files with 780 additions and 62 deletions
@@ -4,7 +4,7 @@
---
## ▶ Continuation State (last updated 2026-04-28)
## ▶ Continuation State (last updated 2026-04-29)
Pick up here if resuming on a new device or session.
@@ -18,8 +18,8 @@ Pick up here if resuming on a new device or session.
| 4 | MainApp two-column layout | ✅ Done | |
| 5 | HubRow + UserBar | ✅ Done | `colorToCss` extracted to `src/utils/color.js` (shared), stub buttons `disabled` |
| 6 | ConnectionItem + ConnectionList + Sidebar | ✅ Done | `h-full` on Sidebar, search fallback for unresolved users, `min-w-0` truncate fix |
| 7 | MessageItem + MessageList + MessageInput + ChatArea | 🔄 Created, review **interrupted** — needs spec + quality review before proceeding |
| 8 | End-to-end verification | ⬜ Pending | Run `pnpm dev` in `client/`, manual browser smoke test (see task for steps) |
| 7 | MessageItem + MessageList + MessageInput + ChatArea | ✅ Done | Spec + code-quality review passed 2026-04-29; rollback consistent with `sendMessage` rethrow |
| 8 | End-to-end verification | ⏳ Manual only | Static import/dep check passed 2026-04-29. `pnpm dev` browser smoke test (auth, sidebar, DM round-trip, WS) is owner-driven. |
### Extra file created (not in original plan)
@@ -120,7 +120,7 @@ Pick up here if resuming on a new device or session.
- Create: `client/src/api/http.js`
- Create: `client/src/api/ws.js`
- [ ] **Step 1: Create `client/src/api/http.js`**
- [x] **Step 1: Create `client/src/api/http.js`**
```js
const BASE = 'http://localhost:8080'
@@ -138,7 +138,7 @@ export async function apiFetch(method, path, { body, query } = {}) {
}
```
- [ ] **Step 2: Create `client/src/api/ws.js`**
- [x] **Step 2: Create `client/src/api/ws.js`**
```js
let socket = null
@@ -177,7 +177,7 @@ export function wsDisconnect() {
The login response is `{ token, userId }`. Both must be saved to localStorage — `userId` is needed to identify "my" messages and to fetch own profile.
- [ ] **Step 1: Replace `client/src/components/AuthPage.jsx` with wired version**
- [x] **Step 1: Replace `client/src/components/AuthPage.jsx` with wired version**
```jsx
import { useState } from 'react'
@@ -277,7 +277,7 @@ export default function AuthPage() {
}
```
- [ ] **Step 2: Verify in browser**
- [x] **Step 2: Verify in browser** (owner-confirmed, prior session)
Run `pnpm dev` in `client/`. Navigate to `http://localhost:5173/auth`.
- Enter valid credentials → should redirect to `/` (currently shows "Main App")
@@ -293,7 +293,7 @@ Run `pnpm dev` in `client/`. Navigate to `http://localhost:5173/auth`.
`userMap` is a `{ [userId]: userDetails }` dict populated by fetching `GET /user` for each connection's "other" participant. The `selectedIdRef` keeps the WS handler in sync with the current selection without stale closures.
- [ ] **Step 1: Create `client/src/context/AppContext.jsx`**
- [x] **Step 1: Create `client/src/context/AppContext.jsx`**
```jsx
import { createContext, useContext, useReducer, useEffect, useRef, useCallback } from 'react'
@@ -487,7 +487,7 @@ export function useApp() {
**Files:**
- Modify: `client/src/components/MainApp.jsx`
- [ ] **Step 1: Replace `client/src/components/MainApp.jsx`**
- [x] **Step 1: Replace `client/src/components/MainApp.jsx`**
```jsx
import { AppProvider } from '../context/AppContext'
@@ -514,7 +514,7 @@ export default function MainApp() {
- Create: `client/src/components/HubRow.jsx`
- Create: `client/src/components/UserBar.jsx`
- [ ] **Step 1: Create `client/src/components/HubRow.jsx`**
- [x] **Step 1: Create `client/src/components/HubRow.jsx`**
```jsx
export default function HubRow() {
@@ -531,7 +531,7 @@ export default function HubRow() {
}
```
- [ ] **Step 2: Create `client/src/components/UserBar.jsx`**
- [x] **Step 2: Create `client/src/components/UserBar.jsx`**
```jsx
import { useApp } from '../context/AppContext'
@@ -576,7 +576,7 @@ export default function UserBar() {
- Create: `client/src/components/ConnectionList.jsx`
- Create: `client/src/components/Sidebar.jsx`
- [ ] **Step 1: Create `client/src/components/ConnectionItem.jsx`**
- [x] **Step 1: Create `client/src/components/ConnectionItem.jsx`**
The "other user" is whichever of `requestorId`/`recipientId` isn't our `userId`.
@@ -633,7 +633,7 @@ export default function ConnectionItem({ conn }) {
}
```
- [ ] **Step 2: Create `client/src/components/ConnectionList.jsx`**
- [x] **Step 2: Create `client/src/components/ConnectionList.jsx`**
```jsx
import { useState } from 'react'
@@ -675,7 +675,7 @@ export default function ConnectionList() {
}
```
- [ ] **Step 3: Create `client/src/components/Sidebar.jsx`**
- [x] **Step 3: Create `client/src/components/Sidebar.jsx`**
```jsx
import HubRow from './HubRow'
@@ -703,7 +703,7 @@ export default function Sidebar() {
- Create: `client/src/components/MessageInput.jsx`
- Create: `client/src/components/ChatArea.jsx`
- [ ] **Step 1: Create `client/src/components/MessageItem.jsx`**
- [x] **Step 1: Create `client/src/components/MessageItem.jsx`**
Messages are displayed in Discord style: avatar + sender name on first message of a group, compact rows for consecutive same-sender messages.
@@ -761,7 +761,7 @@ export default function MessageItem({ msg, showHeader }) {
}
```
- [ ] **Step 2: Create `client/src/components/MessageList.jsx`**
- [x] **Step 2: Create `client/src/components/MessageList.jsx`**
Groups consecutive messages from the same sender so that only the first shows the header (avatar + name).
@@ -791,7 +791,7 @@ export default function MessageList() {
}
```
- [ ] **Step 3: Create `client/src/components/MessageInput.jsx`**
- [x] **Step 3: Create `client/src/components/MessageInput.jsx`**
```jsx
import { useState, useRef } from 'react'
@@ -845,7 +845,7 @@ export default function MessageInput() {
}
```
- [ ] **Step 4: Create `client/src/components/ChatArea.jsx`**
- [x] **Step 4: Create `client/src/components/ChatArea.jsx`**
```jsx
import { useApp } from '../context/AppContext'
@@ -908,6 +908,8 @@ export default function ChatArea() {
## Task 8: End-to-End Verification
> Steps 16 require a running browser + backend and are owner-driven. Static verification done 2026-04-29: every Task 7 import resolves to an existing file, no missing dependencies in `package.json`.
- [ ] **Step 1: Start the dev server**
In `client/`: