Campaign assignments, ownership-based editing, and role-scoped data
- Add campaign_assignments table for user-to-campaign mapping - Superadmin/managers can assign users to campaigns; visibility filtered by assignment/ownership - Managers can only manage (tracks, assignments) on campaigns they created - Budget controlled by superadmin only, with proper modal UI for editing - Ownership-based editing for campaigns, projects, comments (creators can edit their own) - Role-scoped dashboard and finance data (managers see only their campaigns' data) - Manager's budget derived from sum of their campaign budgets set by superadmin - Hide UI features users cannot use (principle of least privilege across all pages) - Fix profile completion prompt persisting after saving (login response now includes profileComplete) - Add post detail modal in campaign detail with thumbnails, publication links, and metadata - Add comment inline editing for comment authors - Move financial summary cards below filters on Campaigns page Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@ import { useState, useEffect, useContext } from 'react'
|
||||
import { Plus, Search, FolderKanban } from 'lucide-react'
|
||||
import { AppContext } from '../App'
|
||||
import { api } from '../utils/api'
|
||||
import { useAuth } from '../contexts/AuthContext'
|
||||
import ProjectCard from '../components/ProjectCard'
|
||||
import Modal from '../components/Modal'
|
||||
|
||||
@@ -12,6 +13,7 @@ const EMPTY_PROJECT = {
|
||||
|
||||
export default function Projects() {
|
||||
const { teamMembers, brands } = useContext(AppContext)
|
||||
const { permissions } = useAuth()
|
||||
const [projects, setProjects] = useState([])
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [showModal, setShowModal] = useState(false)
|
||||
@@ -81,13 +83,15 @@ export default function Projects() {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<button
|
||||
onClick={() => setShowModal(true)}
|
||||
className="flex items-center gap-2 px-4 py-2 bg-brand-primary text-white rounded-lg text-sm font-medium hover:bg-brand-primary-light shadow-sm ml-auto"
|
||||
>
|
||||
<Plus className="w-4 h-4" />
|
||||
New Project
|
||||
</button>
|
||||
{permissions?.canCreateProjects && (
|
||||
<button
|
||||
onClick={() => setShowModal(true)}
|
||||
className="flex items-center gap-2 px-4 py-2 bg-brand-primary text-white rounded-lg text-sm font-medium hover:bg-brand-primary-light shadow-sm ml-auto"
|
||||
>
|
||||
<Plus className="w-4 h-4" />
|
||||
New Project
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Project grid */}
|
||||
|
||||
Reference in New Issue
Block a user