✨(front) add video conference link generation in event modal
Implement the visio conference feature in the event modal: - Add NEXT_PUBLIC_VISIO_BASE_URL env var for configurable base URL - Create generateVisioRoomId() utility (xxx-xxxx-xxx format, a-z) - Refactor VideoConferenceSection: button to create, link + remove when URL exists - Hide visio pill when env var is not configured (feature flag) - Add removeVisio i18n key in EN/FR/NL The visio URL is stored via the standard ICS URL property, which is already wired through useEventForm.toIcsEvent() and CalDavService. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1 +1,2 @@
|
||||
NEXT_PUBLIC_API_ORIGIN=
|
||||
NEXT_PUBLIC_VISIO_BASE_URL=https://visio.suite.anct.gouv.fr
|
||||
@@ -1 +1,2 @@
|
||||
NEXT_PUBLIC_API_ORIGIN=http://localhost:8921
|
||||
NEXT_PUBLIC_VISIO_BASE_URL=https://visio.suite.anct.gouv.fr
|
||||
|
||||
@@ -119,13 +119,19 @@ export const EventModal = ({
|
||||
}
|
||||
};
|
||||
|
||||
const visioBaseUrl = process.env.NEXT_PUBLIC_VISIO_BASE_URL;
|
||||
|
||||
const pills = useMemo(
|
||||
() => [
|
||||
{
|
||||
id: "videoConference" as const,
|
||||
icon: "videocam",
|
||||
label: t("calendar.event.sections.addVideoConference"),
|
||||
},
|
||||
...(visioBaseUrl
|
||||
? [
|
||||
{
|
||||
id: "videoConference" as const,
|
||||
icon: "videocam",
|
||||
label: t("calendar.event.sections.addVideoConference"),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
{
|
||||
id: "location" as const,
|
||||
icon: "place",
|
||||
@@ -147,7 +153,7 @@ export const EventModal = ({
|
||||
label: t("calendar.event.attendees"),
|
||||
},
|
||||
],
|
||||
[t],
|
||||
[t, visioBaseUrl],
|
||||
);
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Button } from "@gouvfr-lasuite/cunningham-react";
|
||||
import { SectionRow } from "./SectionRow";
|
||||
import { generateVisioRoomId } from "./generateVisioRoomId";
|
||||
|
||||
interface VideoConferenceSectionProps {
|
||||
url: string;
|
||||
@@ -19,14 +19,12 @@ export const VideoConferenceSection = ({
|
||||
onToggle,
|
||||
}: VideoConferenceSectionProps) => {
|
||||
const { t } = useTranslation();
|
||||
const [isCreating, setIsCreating] = useState(false);
|
||||
|
||||
const handleCreateVisio = () => {
|
||||
// Inert for now - will integrate with La Suite API in the future
|
||||
setIsCreating(true);
|
||||
setTimeout(() => {
|
||||
setIsCreating(false);
|
||||
}, 500);
|
||||
const baseUrl = process.env.NEXT_PUBLIC_VISIO_BASE_URL;
|
||||
if (!baseUrl) return;
|
||||
const roomId = generateVisioRoomId();
|
||||
onChange(`${baseUrl}/${roomId}`);
|
||||
};
|
||||
|
||||
const handleRemove = () => {
|
||||
@@ -42,15 +40,35 @@ export const VideoConferenceSection = ({
|
||||
isExpanded={isExpanded}
|
||||
onToggle={onToggle}
|
||||
>
|
||||
<Button
|
||||
size="small"
|
||||
color="neutral"
|
||||
variant="tertiary"
|
||||
onClick={handleCreateVisio}
|
||||
disabled={isCreating}
|
||||
>
|
||||
{t("calendar.event.sections.createVisio")}
|
||||
</Button>
|
||||
{url ? (
|
||||
<div style={{ display: "flex", alignItems: "center", gap: "8px" }}>
|
||||
<a
|
||||
href={url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
style={{ wordBreak: "break-all" }}
|
||||
>
|
||||
{url}
|
||||
</a>
|
||||
<Button
|
||||
size="small"
|
||||
color="neutral"
|
||||
variant="tertiary"
|
||||
icon={<span className="material-icons">close</span>}
|
||||
onClick={handleRemove}
|
||||
aria-label={t("calendar.event.sections.removeVisio")}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<Button
|
||||
size="small"
|
||||
color="neutral"
|
||||
variant="tertiary"
|
||||
onClick={handleCreateVisio}
|
||||
>
|
||||
{t("calendar.event.sections.createVisio")}
|
||||
</Button>
|
||||
)}
|
||||
</SectionRow>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
const randomLetters = (n: number): string =>
|
||||
Array.from({ length: n }, () =>
|
||||
String.fromCharCode(97 + Math.floor(Math.random() * 26)),
|
||||
).join("");
|
||||
|
||||
export const generateVisioRoomId = (): string =>
|
||||
`${randomLetters(3)}-${randomLetters(4)}-${randomLetters(3)}`;
|
||||
@@ -137,6 +137,7 @@
|
||||
"addLocation": "Add location",
|
||||
"addVideoConference": "Visio",
|
||||
"createVisio": "Add video conference",
|
||||
"removeVisio": "Remove video conference",
|
||||
"videoLink": "Video conference link",
|
||||
"addAttendees": "Add participants",
|
||||
"addDescription": "Add description",
|
||||
@@ -747,6 +748,7 @@
|
||||
"addLocation": "Ajouter un lieu",
|
||||
"addVideoConference": "Visio",
|
||||
"createVisio": "Ajouter une visioconférence",
|
||||
"removeVisio": "Supprimer la visioconférence",
|
||||
"videoLink": "Lien de visioconférence",
|
||||
"addAttendees": "Ajouter des participants",
|
||||
"addDescription": "Ajouter une description",
|
||||
@@ -1104,6 +1106,7 @@
|
||||
"addLocation": "Locatie toevoegen",
|
||||
"addVideoConference": "Visio",
|
||||
"createVisio": "Add video conference",
|
||||
"removeVisio": "Videoconferentie verwijderen",
|
||||
"videoLink": "Videoconferentie link",
|
||||
"addAttendees": "Deelnemers toevoegen",
|
||||
"addDescription": "Beschrijving toevoegen",
|
||||
|
||||
Reference in New Issue
Block a user