Session 2026-05-28: profile page overhaul, nav fixes, dashboard activity links
- Fix nav links not working from profile page (useEffect infinite re-render via unstable profile object ref)
- Fix nav hover/active: gold icon highlight, no background change; active links non-clickable
- Fix hover layout shift: add border: 1px solid transparent to all interactive elements
- Header icon buttons (search, theme toggle) now highlight gold on hover
- Profile page: replace calendar with activity feed (60/40 grid), add stat cards (tasks completed, active projects, revision requests, submissions)
- Profile card: title field, icon rows for location/email/linkedin, member since + role bottom-right, edit button top-right
- Profile portrait: remove wrapper column, fix left-gap alignment
- Add profiles.title migration
- Dashboard recent activity: name → /profile/{id}, task → /requests/{id} (clickable links)
- Icon-only sidebar with gold active/hover state, pointer-events: none on active links
- layout.md updated with profile page geometry rules
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -41,7 +41,7 @@ function FileIcon({ entry }) {
|
||||
const ext = (entry.name.includes('.') ? entry.name.split('.').pop() : '').toUpperCase().slice(0, 4) || 'FILE';
|
||||
const { bg, color } = fileIconStyle(ext);
|
||||
return (
|
||||
<span className="file-icon" style={{ background: bg, color, border: 'none', fontSize: 9, fontWeight: 700, letterSpacing: 0.4, fontFamily: 'monospace' }}>
|
||||
<span className="file-icon" style={{ background: bg, color, border: 'none', fontSize: 9, fontWeight: 400, letterSpacing: 0.4, fontFamily: 'monospace' }}>
|
||||
{ext}
|
||||
</span>
|
||||
);
|
||||
@@ -497,7 +497,7 @@ export default function FileBrowser({ initialPath = '/', rootPath = '/', showSyn
|
||||
placeholder="Folder name"
|
||||
autoFocus
|
||||
disabled={!configured || loading || Boolean(working)}
|
||||
style={{ fontSize: 13, padding: '4px 8px', borderRadius: 6, border: '1px solid var(--border)', background: 'var(--input-bg)', color: 'var(--text-primary)', width: 160 }}
|
||||
style={{ fontSize: 13, padding: '4px 8px', borderRadius: 4, border: '1px solid var(--border)', background: 'var(--input-bg)', color: 'var(--text-primary)', width: 160 }}
|
||||
/>
|
||||
<LoadingButton type="submit" className="btn btn-outline btn-sm" loading={working === 'mkdir'} disabled={!folderName.trim() || !configured || loading || Boolean(working)} loadingText="Creating...">
|
||||
Create
|
||||
@@ -589,7 +589,7 @@ export default function FileBrowser({ initialPath = '/', rootPath = '/', showSyn
|
||||
onDragOver={isDragTarget ? (e) => handleFolderDragOver(e, entry) : undefined}
|
||||
onDragLeave={isDragTarget ? handleFolderDragLeave : undefined}
|
||||
onDrop={isDragTarget ? (e) => handleFolderDrop(e, entry) : undefined}
|
||||
style={isDragOver ? { outline: '2px solid var(--accent)', borderRadius: 6 } : undefined}
|
||||
style={isDragOver ? { outline: '2px solid var(--accent)', borderRadius: 4 } : undefined}
|
||||
>
|
||||
<FileIcon entry={entry} />
|
||||
{isRenaming ? (
|
||||
@@ -600,7 +600,7 @@ export default function FileBrowser({ initialPath = '/', rootPath = '/', showSyn
|
||||
onChange={(e) => setRenameValue(e.target.value)}
|
||||
autoFocus
|
||||
disabled={Boolean(working)}
|
||||
style={{ fontSize: 13, padding: '2px 8px', borderRadius: 6, border: '1px solid var(--border)', background: 'var(--input-bg)', color: 'var(--text-primary)', flex: 1, minWidth: 0 }}
|
||||
style={{ fontSize: 13, padding: '2px 8px', borderRadius: 4, border: '1px solid var(--border)', background: 'var(--input-bg)', color: 'var(--text-primary)', flex: 1, minWidth: 0 }}
|
||||
onKeyDown={(e) => { if (e.key === 'Escape') setRenamingEntry(null); }}
|
||||
/>
|
||||
<LoadingButton type="submit" className="btn btn-outline btn-sm" loading={working === `rename:${entry.path}`} disabled={!renameValue.trim() || Boolean(working)} loadingText="Renaming...">
|
||||
|
||||
Reference in New Issue
Block a user