diff --git a/client/src/App.tsx b/client/src/App.tsx
index 098c544..c30b015 100644
--- a/client/src/App.tsx
+++ b/client/src/App.tsx
@@ -435,6 +435,8 @@ function App() {
const logbookReadOnly =
activeLogbookRecord?.isShared === 1 && activeAccessRole === 'READ'
+ const isLogbookOwner =
+ activeAccessRole === 'OWNER' || activeLogbookRecord?.isShared !== 1
if (!activeLogbookId) {
return (
@@ -581,11 +583,15 @@ function App() {
)}
{activeTab === 'vessel' && (
-
+
)}
{activeTab === 'crew' && (
-
+
)}
{activeTab === 'stats' && activeLogbookId && activeLogbookTitle && (
diff --git a/client/src/components/CrewForm.tsx b/client/src/components/CrewForm.tsx
index d8da019..ebaeaf0 100644
--- a/client/src/components/CrewForm.tsx
+++ b/client/src/components/CrewForm.tsx
@@ -12,6 +12,7 @@ import { Users, User, Plus, Trash2, Edit2, Save, X, Check, Camera } from 'lucide
interface CrewFormProps {
logbookId: string
readOnly?: boolean
+ skipperReadOnly?: boolean
preloadedData?: any[]
}
@@ -34,9 +35,15 @@ interface DecryptedCrew {
data: CrewMemberData
}
-export default function CrewForm({ logbookId, readOnly = false, preloadedData }: CrewFormProps) {
+export default function CrewForm({
+ logbookId,
+ readOnly = false,
+ skipperReadOnly = false,
+ preloadedData
+}: CrewFormProps) {
const { t } = useTranslation()
const { showConfirm } = useDialog()
+ const skipperFormReadOnly = readOnly || skipperReadOnly
// Skipper profile state
const [skipName, setSkipName] = useState('')
@@ -192,7 +199,7 @@ export default function CrewForm({ logbookId, readOnly = false, preloadedData }:
const handleSaveSkipper = async (e: React.FormEvent) => {
e.preventDefault()
- if (readOnly) return
+ if (skipperFormReadOnly) return
setSavingSkipper(true)
setError(null)
setSkipperSuccess(false)
@@ -397,10 +404,14 @@ export default function CrewForm({ logbookId, readOnly = false, preloadedData }:
{error &&
{error}
}
+ {skipperReadOnly && !readOnly && (
+ {t('crew.skipper_read_only_hint')}
+ )}
+