From b917972f5e27e835a353a76a9e1a2d2e62a7e6e0 Mon Sep 17 00:00:00 2001 From: Randall Stillwell Date: Fri, 25 Jul 2025 10:29:45 -0500 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=84=20Simplified=20Permission=20Model?= =?UTF-8?q?=20&=20UX=20Improvements?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🎯 Cleaner Permission System: - Collections are private/invite-only by default - Public toggle only controls community visibility (not edit permissions) - Simplified to: Creator + Invited Collaborators can edit, everyone else view-only - Only creator can delete collections 📝 UI/UX Enhancements: - Changed 'Invite User' to 'Invite Collaborator' with clearer messaging - Replaced visibility dropdown with clean public/private toggle - Updated role descriptions: 'Collaborator' (editor) and 'Viewer' - Default invitation role is now 'editor' (collaborator) - Added explanatory text about collaboration purpose 🔐 Permission Logic Updates: - Public collections: visible in community but invite-only editing - Private collections: hidden from community, invite-only editing - Removed complex visibility states (invite-only/private distinction) - Updated permission middleware for simplified model 📧 Email Template Updates: - Clearer role descriptions in invitation emails - Focus on collaboration and card management permissions - Removed owner role from invitation options 🗄️ Database Schema Updates: - Updated APIs to use is_public boolean instead of visibility enum - Maintained backward compatibility with existing data - Simplified permission checking logic The system now has a much cleaner UX: collections are collaborative workspaces that can optionally be made visible to the community! 🚀 --- components/BulkInviteModal.js | 9 ++-- components/CollaborationManager.js | 30 ++++++------- components/PermissionIndicator.js | 51 ++++++++--------------- lib/permission-middleware.js | 13 +++--- pages/api/collections.js | 27 ++++++------ pages/api/collections/[id].js | 10 ++--- pages/api/collections/[id]/permissions.js | 19 ++++----- pages/collections.js | 37 +++++++++------- 8 files changed, 88 insertions(+), 108 deletions(-) diff --git a/components/BulkInviteModal.js b/components/BulkInviteModal.js index 9298a63..12cd2ed 100644 --- a/components/BulkInviteModal.js +++ b/components/BulkInviteModal.js @@ -3,7 +3,7 @@ import { useState } from 'react'; export default function BulkInviteModal({ collectionId, isOpen, onClose, onSuccess }) { const [inviteData, setInviteData] = useState({ emails: '', - role: 'viewer', + role: 'editor', message: '' }); const [processing, setProcessing] = useState(false); @@ -63,7 +63,7 @@ export default function BulkInviteModal({ collectionId, isOpen, onClose, onSucce }; const handleClose = () => { - setInviteData({ emails: '', role: 'viewer', message: '' }); + setInviteData({ emails: '', role: 'editor', message: '' }); setResults(null); onClose(); }; @@ -121,9 +121,8 @@ user4@example.com" color: 'var(--text-primary)' }} > - - - + + diff --git a/components/CollaborationManager.js b/components/CollaborationManager.js index 34e9af3..a1b5d73 100644 --- a/components/CollaborationManager.js +++ b/components/CollaborationManager.js @@ -8,7 +8,7 @@ export default function CollaborationManager({ collectionId, isOwner }) { const [showBulkInviteModal, setShowBulkInviteModal] = useState(false); const [inviteForm, setInviteForm] = useState({ email: '', - role: 'viewer', + role: 'editor', message: '' }); const [inviting, setInviting] = useState(false); @@ -48,7 +48,7 @@ export default function CollaborationManager({ collectionId, isOwner }) { if (response.ok) { setShowInviteModal(false); - setInviteForm({ email: '', role: 'viewer', message: '' }); + setInviteForm({ email: '', role: 'editor', message: '' }); fetchPermissions(); // Refresh the list } else { const error = await response.json(); @@ -153,15 +153,15 @@ export default function CollaborationManager({ collectionId, isOwner }) { {isOwner && (
- +