[#82] added cozy-ui for internationnalisation (#267)

Co-authored-by: Camille Moussu <cmoussu@linagora.com>
This commit is contained in:
Camille Moussu
2025-11-06 15:46:58 +01:00
committed by GitHub
parent c1f37e3ebd
commit 36bc027d6d
49 changed files with 12003 additions and 5002 deletions
+103 -63
View File
@@ -42,9 +42,9 @@ import { renderAttendeeBadge } from "../../components/Event/utils/eventUtils";
import { getCalendarRange } from "../../utils/dateUtils";
import { deleteEventAsync } from "../Calendars/CalendarSlice";
import { dlEvent } from "./EventApi";
import EventDisplayModal from "./EventDisplay";
import { CalendarEvent } from "./EventsTypes";
import EventUpdateModal from "./EventUpdateModal";
import { useI18n } from "cozy-ui/transpiled/react/providers/I18n";
export default function EventPreviewModal({
eventId,
calId,
@@ -58,6 +58,7 @@ export default function EventPreviewModal({
open: boolean;
onClose: (event: {}, reason: "backdropClick" | "escapeKeyDown") => void;
}) {
const { t } = useI18n();
const dispatch = useAppDispatch();
const calendars = useAppSelector((state) => state.calendars);
const timezone =
@@ -75,7 +76,6 @@ export default function EventPreviewModal({
const isRecurring = event?.uid?.includes("/");
const isOwn = calendar.ownerEmails?.includes(user.userData.email);
const [showAllAttendees, setShowAllAttendees] = useState(false);
const [openFullDisplay, setOpenFullDisplay] = useState(false);
const [openUpdateModal, setOpenUpdateModal] = useState(false);
const [openDuplicateModal, setOpenDuplicateModal] = useState(false);
const [hidePreview, setHidePreview] = useState(false);
@@ -210,7 +210,7 @@ export default function EventPreviewModal({
)
}
>
Email attendees
{t("eventPreview.emailAttendees")}
</MenuItem>
)}
<EventDuplication
@@ -254,7 +254,7 @@ export default function EventPreviewModal({
updateTempList();
}}
>
Delete event
{t("eventPreview.deleteEvent")}
</MenuItem>
)}
</Menu>
@@ -270,9 +270,7 @@ export default function EventPreviewModal({
{event.class === "PRIVATE" &&
(isOwn ? (
<Tooltip
title={
"Only you and attendees can see the details of this event."
}
title={t("eventPreview.privateEvent.tooltipOwn")}
placement="top"
>
<LockOutlineIcon />
@@ -294,23 +292,21 @@ export default function EventPreviewModal({
</Typography>
{event.transp === "TRANSPARENT" && (
<Tooltip
title={
"Others see you as available during the time range of this event."
}
title={t("eventPreview.free.tooltip")}
placement="top"
>
<Chip
icon={<CircleIcon color="success" fontSize="small" />}
label="Free"
label={t("eventPreview.free.label")}
/>
</Tooltip>
)}
</Box>
<Typography color="text.secondaryContainer" gutterBottom>
{formatDate(event.start, event.allday)}
{formatDate(event.start, t, event.allday)}
{event.end &&
formatEnd(event.start, event.end, event.allday) &&
` ${formatEnd(event.start, event.end, event.allday)} ${!event.allday && getTimezoneOffset(timezone)}`}
formatEnd(event.start, event.end, t, event.allday) &&
` ${formatEnd(event.start, event.end, t, event.allday)} ${!event.allday && getTimezoneOffset(timezone)}`}
</Typography>
</>
)
@@ -319,7 +315,9 @@ export default function EventPreviewModal({
<>
{currentUserAttendee && (
<>
<Typography sx={{ marginRight: 2 }}>Attending?</Typography>
<Typography sx={{ marginRight: 2 }}>
{t("eventPreview.attendingQuestion")}
</Typography>
<Box display="flex" gap="15px" alignItems="center">
<Button
variant={
@@ -344,7 +342,6 @@ export default function EventPreviewModal({
user,
event,
"ACCEPTED",
onClose,
type,
calendarList
@@ -363,7 +360,7 @@ export default function EventPreviewModal({
}
}}
>
Accept
{t("eventPreview.accept")}
</Button>
<Button
variant={
@@ -406,7 +403,7 @@ export default function EventPreviewModal({
}
}}
>
Maybe
{t("eventPreview.maybe")}
</Button>
<Button
variant={
@@ -449,7 +446,7 @@ export default function EventPreviewModal({
}
}}
>
Decline
{t("eventPreview.decline")}
</Button>
</Box>
</>
@@ -474,7 +471,7 @@ export default function EventPreviewModal({
window.open(event.x_openpass_videoconference)
}
>
Join the video conference
{t("eventPreview.joinVideo")}
</Button>
}
/>
@@ -497,20 +494,25 @@ export default function EventPreviewModal({
}}
>
<Box sx={{ marginRight: 2 }}>
<Typography>{attendees.length} guests</Typography>
<Typography>
{t("eventPreview.guests", {
count: attendees.length,
})}
</Typography>
<Typography
sx={{ fontSize: "13px", color: "text.secondary" }}
>
{
attendees.filter((a) => a.partstat === "ACCEPTED")
.length
}{" "}
yes,{" "}
{
attendees.filter((a) => a.partstat === "DECLINED")
.length
}{" "}
no
{t("eventPreview.yesCount", {
count: attendees.filter(
(a) => a.partstat === "ACCEPTED"
).length,
})}
,{" "}
{t("eventPreview.noCount", {
count: attendees.filter(
(a) => a.partstat === "DECLINED"
).length,
})}
</Typography>
</Box>
{!showAllAttendees && (
@@ -519,6 +521,7 @@ export default function EventPreviewModal({
renderAttendeeBadge(
organizer,
"org",
t,
showAllAttendees,
true
)}
@@ -526,6 +529,7 @@ export default function EventPreviewModal({
renderAttendeeBadge(
a,
idx.toString(),
t,
showAllAttendees
)
)}
@@ -541,7 +545,9 @@ export default function EventPreviewModal({
}}
onClick={() => setShowAllAttendees(!showAllAttendees)}
>
{showAllAttendees ? "Show less" : `Show more `}
{showAllAttendees
? t("eventPreview.showLess")
: t("eventPreview.showMore")}
</Typography>
</Box>
}
@@ -550,10 +556,10 @@ export default function EventPreviewModal({
)}
{showAllAttendees &&
organizer &&
renderAttendeeBadge(organizer, "org", showAllAttendees, true)}
renderAttendeeBadge(organizer, "org", t, showAllAttendees, true)}
{showAllAttendees &&
visibleAttendees.map((a, idx) =>
renderAttendeeBadge(a, idx.toString(), showAllAttendees)
renderAttendeeBadge(a, idx.toString(), t, showAllAttendees)
)}
{/* Location */}
{event.location && (
@@ -593,7 +599,10 @@ export default function EventPreviewModal({
<NotificationsNoneIcon />
</Box>
}
text={`${event.alarm.trigger} before by ${event.alarm.action}`}
text={t("eventPreview.alarmText", {
trigger: t(`event.form.notifications.${event.alarm.trigger}`),
action: t(`event.form.notifications.${event.alarm.action}`),
})}
style={{
fontSize: "16px",
fontFamily: "'Inter', sans-serif",
@@ -608,7 +617,7 @@ export default function EventPreviewModal({
<RepeatIcon />
</Box>
}
text={makeRecurrenceString(event)}
text={makeRecurrenceString(event, t)}
style={{
fontSize: "16px",
fontFamily: "'Inter', sans-serif",
@@ -636,7 +645,7 @@ export default function EventPreviewModal({
letterSpacing={"0.5px"}
textAlign={"center"}
>
This is a private event. Details are hidden.
{t("eventPreview.privateEvent.hiddenDetails")}
</Typography>
</Box>
)}
@@ -680,13 +689,6 @@ export default function EventPreviewModal({
afterChoiceFunc && afterChoiceFunc(type);
}}
/>
<EventDisplayModal
open={openFullDisplay}
onClose={() => setOpenFullDisplay(false)}
eventId={eventId}
calId={calId}
typeOfAction={typeOfAction}
/>
<EventUpdateModal
open={openUpdateModal}
onClose={() => {
@@ -725,43 +727,76 @@ export default function EventPreviewModal({
);
}
function makeRecurrenceString(event: CalendarEvent): string | undefined {
if (!event.repetition) {
return;
}
const recur = [`Reccurent Event · ${event.repetition.freq}`];
function makeRecurrenceString(
event: CalendarEvent,
t: Function
): string | undefined {
if (!event.repetition) return;
const recur: string[] = [
`${t("eventPreview.recurrentEvent")} · ${t(
`eventPreview.freq.${event.repetition.freq}`,
event.repetition.freq
)}`,
];
const recurType: Record<string, string> = {
daily: "days",
monthly: "months",
yearly: "years",
daily: t("eventPreview.days"),
monthly: t("eventPreview.months"),
yearly: t("eventPreview.years"),
};
if (event.repetition.byday) {
recur.push(`on ${event.repetition.byday.join(", ")}`);
recur.push(
t("eventPreview.recurrenceOnDays", {
days: event.repetition.byday
.map((s) => t(`eventPreview.onDays.${s}`))
.join(", "),
})
);
}
if (event.repetition.interval && event.repetition.interval > 1) {
recur.push(
`every ${event.repetition.interval} ${recurType[event.repetition.freq]}`
t("eventPreview.everyInterval", {
interval: event.repetition.interval,
unit: recurType[event.repetition.freq],
})
);
}
if (event.repetition.occurrences) {
recur.push(`for ${event.repetition.occurrences} occurences`);
recur.push(
t("eventPreview.forOccurrences", {
count: event.repetition.occurrences,
})
);
}
if (event.repetition.endDate) {
recur.push(`until ${event.repetition.endDate}`);
recur.push(
t("eventPreview.until", {
date: new Date(event.repetition.endDate).toLocaleDateString(
t("locale"),
{
year: "numeric",
month: "long",
day: "numeric",
}
),
})
);
}
return recur.join(", ");
}
function formatDate(date: Date | string, allday?: boolean) {
function formatDate(date: Date | string, t: Function, allday?: boolean) {
if (allday) {
return new Date(date).toLocaleDateString(undefined, {
return new Date(date).toLocaleDateString(t("locale"), {
year: "numeric",
month: "long",
weekday: "long",
day: "numeric",
});
} else {
return new Date(date).toLocaleString(undefined, {
return new Date(date).toLocaleString(t("locale"), {
year: "numeric",
month: "long",
weekday: "long",
@@ -772,7 +807,12 @@ function formatDate(date: Date | string, allday?: boolean) {
}
}
function formatEnd(start: Date | string, end: Date | string, allday?: boolean) {
function formatEnd(
start: Date | string,
end: Date | string,
t: Function,
allday?: boolean
) {
const startDate = new Date(start);
const endDate = new Date(end);
@@ -784,19 +824,19 @@ function formatEnd(start: Date | string, end: Date | string, allday?: boolean) {
if (allday) {
return sameDay
? null
: endDate.toLocaleDateString(undefined, {
: endDate.toLocaleDateString(t("locale"), {
year: "numeric",
month: "short",
day: "numeric",
});
} else {
if (sameDay) {
return endDate.toLocaleTimeString(undefined, {
return endDate.toLocaleTimeString(t("locale"), {
hour: "2-digit",
minute: "2-digit",
});
}
return endDate.toLocaleString(undefined, {
return endDate.toLocaleString(t("locale"), {
year: "numeric",
month: "short",
day: "numeric",