Files
reflector/www/app/[domain]/transcripts/shareAndPrivacy.tsx
2024-01-25 13:59:47 +01:00

149 lines
4.6 KiB
TypeScript

import { useEffect, useState } from "react";
import { featureEnabled } from "../domainContext";
import { ShareMode, toShareMode } from "../../lib/shareMode";
import { GetTranscript, GetTranscriptTopic, UpdateTranscript } from "../../api";
import {
Box,
Heading,
IconButton,
Modal,
ModalBody,
ModalContent,
ModalHeader,
ModalOverlay,
Text,
} from "@chakra-ui/react";
import { FaShare } from "react-icons/fa";
import { useFiefUserinfo } from "@fief/fief/build/esm/nextjs/react";
import useApi from "../../lib/useApi";
import { Select } from "chakra-react-select";
import ShareLink from "./shareLink";
import ShareCopy from "./shareCopy";
import ShareZulip from "./shareZulip";
type ShareAndPrivacyProps = {
finalSummaryRef: any;
transcriptResponse: GetTranscript;
topicsResponse: GetTranscriptTopic[];
};
type ShareOption = { value: ShareMode; label: string };
const shareOptions = [
{ label: "Private", value: toShareMode("private") },
{ label: "Secure", value: toShareMode("semi-private") },
{ label: "Public", value: toShareMode("public") },
];
export default function ShareAndPrivacy(props: ShareAndPrivacyProps) {
const [showModal, setShowModal] = useState(false);
const [isOwner, setIsOwner] = useState(false);
const [shareMode, setShareMode] = useState<ShareOption>(
shareOptions.find(
(option) => option.value === props.transcriptResponse.share_mode,
) || shareOptions[0],
);
const [shareLoading, setShareLoading] = useState(false);
const requireLogin = featureEnabled("requireLogin");
const api = useApi();
const updateShareMode = async (selectedShareMode: any) => {
if (!api)
throw new Error("ShareLink's API should always be ready at this point");
setShareLoading(true);
const requestBody: UpdateTranscript = {
share_mode: toShareMode(selectedShareMode.value),
};
const updatedTranscript = await api.v1TranscriptUpdate(
props.transcriptResponse.id,
requestBody,
);
setShareMode(
shareOptions.find(
(option) => option.value === updatedTranscript.share_mode,
) || shareOptions[0],
);
setShareLoading(false);
};
const userId = useFiefUserinfo()?.sub;
useEffect(() => {
setIsOwner(!!(requireLogin && userId === props.transcriptResponse.user_id));
}, [userId, props.transcriptResponse.user_id]);
return (
<>
<IconButton
icon={<FaShare />}
onClick={() => setShowModal(true)}
aria-label="Share"
/>
<Modal
isOpen={!!showModal}
onClose={() => setShowModal(false)}
size={"xl"}
>
<ModalOverlay />
<ModalContent>
<ModalHeader>Share</ModalHeader>
<ModalBody>
{requireLogin && (
<Box mb={4}>
<Text size="sm" mb="2" fontWeight={"bold"}>
Share mode
</Text>
<Text size="sm" mb="2">
{shareMode.value === "private" &&
"This transcript is private and can only be accessed by you."}
{shareMode.value === "semi-private" &&
"This transcript is secure. Only authenticated users can access it."}
{shareMode.value === "public" &&
"This transcript is public. Everyone can access it."}
</Text>
{isOwner && api && (
<Select
options={
[
{ value: "private", label: "Private" },
{ label: "Secure", value: "semi-private" },
{ label: "Public", value: "public" },
] as any
}
value={shareMode}
onChange={updateShareMode}
isLoading={shareLoading}
/>
)}
</Box>
)}
<Text size="sm" mb="2" fontWeight={"bold"}>
Share options
</Text>
{!requireLogin ||
(shareMode.value !== "private" && (
<ShareZulip
transcriptResponse={props.transcriptResponse}
topicsResponse={props.topicsResponse}
/>
))}
<ShareCopy
finalSummaryRef={props.finalSummaryRef}
transcriptResponse={props.transcriptResponse}
topicsResponse={props.topicsResponse}
mb={2}
/>
<ShareLink transcriptId={props.transcriptResponse.id} />
</ModalBody>
</ModalContent>
</Modal>
</>
);
}