feat: project detail overhaul, realtime updates, avatar RLS fix
- ProjectDetail: full redesign — icon meta row, completion progress bar, main contact card, activity feed, subcontractor management modal with multi-select - ProjectDetail: task table matches Tasks.jsx (R#, assigned avatar, priority, type, deadline, status) with status tabs + counts - Realtime: useRefetchOnFocus + useRealtimeSubscription hooks wired to Tasks, TaskDetail, ProjectDetail, TeamDashboard - AuthContext: live profile updates via Supabase realtime channel - Tasks/ProjectDetail: assignee avatar join added for all roles (client, external, team) - RLS: allow all authenticated users to read profiles (fixes avatar display across roles) - RequestForm: lockedFields prop for pre-filled read-only company/project fields Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { useState, useEffect, useRef } from 'react';
|
||||
import { useState, useEffect, useRef, useCallback } from 'react';
|
||||
import { useParams, Link } from 'react-router-dom';
|
||||
import Layout from '../components/Layout';
|
||||
import PageLoader from '../components/PageLoader';
|
||||
@@ -11,6 +11,8 @@ import JSZip from 'jszip';
|
||||
import { popupOverlayStyle, popupSurfaceStyle } from '../lib/popupStyles';
|
||||
import { sendEmail } from '../lib/email';
|
||||
import { uploadFilesToRequestInfo, safeName } from '../lib/filebrowserFolders';
|
||||
import { useRefetchOnFocus } from '../hooks/useRefetchOnFocus';
|
||||
import { useRealtimeSubscription } from '../hooks/useRealtimeSubscription';
|
||||
|
||||
const ACTION_LABEL = {
|
||||
task_created: 'created this task', task_started: 'started this task', task_on_hold: 'placed task on hold',
|
||||
@@ -201,6 +203,10 @@ function SubmissionFiles({ files, downloading, onDownloadAll }) {
|
||||
export default function TaskDetail() {
|
||||
const { id } = useParams();
|
||||
const { currentUser } = useAuth();
|
||||
const [refreshKey, setRefreshKey] = useState(0);
|
||||
const refresh = useCallback(() => setRefreshKey(k => k + 1), []);
|
||||
useRefetchOnFocus(refresh);
|
||||
useRealtimeSubscription(['tasks', 'submissions', 'activity_log', 'task_comments'], refresh);
|
||||
const [task, setTask] = useState(null);
|
||||
const [submissions, setSubmissions] = useState([]);
|
||||
const [activityLog, setActivityLog] = useState([]);
|
||||
@@ -255,7 +261,7 @@ export default function TaskDetail() {
|
||||
setComments(commentData || []);
|
||||
setLoading(false);
|
||||
});
|
||||
}, [id]);
|
||||
}, [id, refreshKey]);
|
||||
|
||||
if (loading) return <Layout><PageLoader /></Layout>;
|
||||
if (!task) return <Layout><p style={{ padding: 24 }}>Task not found.</p></Layout>;
|
||||
|
||||
Reference in New Issue
Block a user