diff --git a/components/ActiveLink.tsx b/components/ActiveLink.tsx deleted file mode 100644 index 7f6e5d32..00000000 --- a/components/ActiveLink.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import Link from "next/link"; -import { useRouter } from "next/router"; -import React, { Children } from "react"; - -const ActiveLink = ({ children, activeClassName, ...props }) => { - const { asPath } = useRouter(); - const child = Children.only(children); - const childClassName = child.props.className || ""; - - const className = - asPath === props.href || asPath === props.as - ? `${childClassName} ${activeClassName}`.trim() - : childClassName; - - return {React.cloneElement(child, { className })}; -}; - -ActiveLink.defaultProps = { - activeClassName: "active", -} as Partial; - -export default ActiveLink; diff --git a/components/I18nLanguageHandler.tsx b/components/I18nLanguageHandler.tsx new file mode 100644 index 00000000..a76ccc25 --- /dev/null +++ b/components/I18nLanguageHandler.tsx @@ -0,0 +1,22 @@ +import { useTranslation } from "next-i18next"; +import { useRouter } from "next/router"; + +interface Props { + localeProp: string; +} + +const I18nLanguageHandler = ({ localeProp }: Props): null => { + const { i18n } = useTranslation("common"); + const router = useRouter(); + const { pathname } = router; + if (!localeProp) + console.warn( + `You may forgot to return 'localeProp' from 'getServerSideProps' or 'getStaticProps' in ${pathname}` + ); + if (i18n.language !== localeProp) { + i18n.changeLanguage(localeProp); + } + return null; +}; + +export default I18nLanguageHandler; diff --git a/components/booking/AvailableTimes.tsx b/components/booking/AvailableTimes.tsx index 1706495b..e4ea2008 100644 --- a/components/booking/AvailableTimes.tsx +++ b/components/booking/AvailableTimes.tsx @@ -11,7 +11,6 @@ import { useSlots } from "@lib/hooks/useSlots"; import Loader from "@components/Loader"; type AvailableTimesProps = { - localeProp: string; workingHours: { days: number[]; startTime: number; @@ -29,7 +28,6 @@ type AvailableTimesProps = { }; const AvailableTimes: FC = ({ - localeProp, date, eventLength, eventTypeId, @@ -39,7 +37,7 @@ const AvailableTimes: FC = ({ users, schedulingType, }) => { - const { t } = useLocale({ localeProp: localeProp }); + const { t } = useLocale(); const router = useRouter(); const { rescheduleUid } = router.query; @@ -68,7 +66,11 @@ const AvailableTimes: FC = ({ {!loading && slots?.length > 0 && slots.map((slot) => { - const bookingUrl = { + type BookingURL = { + pathname: string; + query: Record; + }; + const bookingUrl: BookingURL = { pathname: "book", query: { ...router.query, @@ -78,7 +80,7 @@ const AvailableTimes: FC = ({ }; if (rescheduleUid) { - bookingUrl.query.rescheduleUid = rescheduleUid; + bookingUrl.query.rescheduleUid = rescheduleUid as string; } if (schedulingType === SchedulingType.ROUND_ROBIN) { diff --git a/components/booking/BookingListItem.tsx b/components/booking/BookingListItem.tsx index 52e2cd03..7ee04741 100644 --- a/components/booking/BookingListItem.tsx +++ b/components/booking/BookingListItem.tsx @@ -6,7 +6,7 @@ import { useMutation } from "react-query"; import { HttpError } from "@lib/core/http/error"; import { inferQueryOutput, trpc } from "@lib/trpc"; -import TableActions from "@components/ui/TableActions"; +import TableActions, { ActionType } from "@components/ui/TableActions"; type BookingItem = inferQueryOutput<"viewer.bookings">[number]; @@ -34,7 +34,7 @@ function BookingListItem(booking: BookingItem) { const isUpcoming = new Date(booking.endTime) >= new Date(); const isCancelled = booking.status === BookingStatus.CANCELLED; - const pendingActions = [ + const pendingActions: ActionType[] = [ { id: "reject", label: "Reject", @@ -52,7 +52,7 @@ function BookingListItem(booking: BookingItem) { }, ]; - const bookedActions = [ + const bookedActions: ActionType[] = [ { id: "cancel", label: "Cancel", diff --git a/components/booking/DatePicker.tsx b/components/booking/DatePicker.tsx index 9b711ae5..58ec01c0 100644 --- a/components/booking/DatePicker.tsx +++ b/components/booking/DatePicker.tsx @@ -14,7 +14,6 @@ dayjs.extend(utc); dayjs.extend(timezone); const DatePicker = ({ - localeProp, weekStart, onDatePicked, workingHours, @@ -28,7 +27,7 @@ const DatePicker = ({ periodCountCalendarDays, minimumBookingNotice, }) => { - const { t } = useLocale({ localeProp: localeProp }); + const { t } = useLocale(); const [days, setDays] = useState<({ disabled: boolean; date: number } | null)[]>([]); const [selectedMonth, setSelectedMonth] = useState( diff --git a/components/booking/TimeOptions.tsx b/components/booking/TimeOptions.tsx index 1d75ed3f..123746d8 100644 --- a/components/booking/TimeOptions.tsx +++ b/components/booking/TimeOptions.tsx @@ -9,7 +9,6 @@ import { useLocale } from "@lib/hooks/useLocale"; import { is24h, timeZone } from "../../lib/clock"; type Props = { - localeProp: string; onSelectTimeZone: (selectedTimeZone: string) => void; onToggle24hClock: (is24hClock: boolean) => void; }; @@ -17,7 +16,7 @@ type Props = { const TimeOptions: FC = (props) => { const [selectedTimeZone, setSelectedTimeZone] = useState(""); const [is24hClock, setIs24hClock] = useState(false); - const { t } = useLocale({ localeProp: props.localeProp }); + const { t } = useLocale(); useEffect(() => { setIs24hClock(is24h()); diff --git a/components/booking/pages/AvailabilityPage.tsx b/components/booking/pages/AvailabilityPage.tsx index 6741f483..a2248e23 100644 --- a/components/booking/pages/AvailabilityPage.tsx +++ b/components/booking/pages/AvailabilityPage.tsx @@ -30,11 +30,11 @@ dayjs.extend(customParseFormat); type Props = AvailabilityTeamPageProps | AvailabilityPageProps; -const AvailabilityPage = ({ profile, eventType, workingHours, localeProp }: Props) => { +const AvailabilityPage = ({ profile, eventType, workingHours }: Props) => { const router = useRouter(); const { rescheduleUid } = router.query; const { isReady } = useTheme(profile.theme); - const { t, locale } = useLocale({ localeProp }); + const { t } = useLocale(); const selectedDate = useMemo(() => { const dateString = asStringOrNull(router.query.date); @@ -188,7 +188,6 @@ const AvailabilityPage = ({ profile, eventType, workingHours, localeProp }: Prop

{eventType.description}

- + ); diff --git a/components/booking/pages/BookingPage.tsx b/components/booking/pages/BookingPage.tsx index 70a9f8a4..4e252bbf 100644 --- a/components/booking/pages/BookingPage.tsx +++ b/components/booking/pages/BookingPage.tsx @@ -13,8 +13,6 @@ import { stringify } from "querystring"; import { useCallback, useEffect, useState } from "react"; import { FormattedNumber, IntlProvider } from "react-intl"; import { ReactMultiEmail } from "react-multi-email"; -import PhoneInput from "react-phone-number-input"; -import "react-phone-number-input/style.css"; import { createPaymentLink } from "@ee/lib/stripe/client"; @@ -30,6 +28,7 @@ import { BookingCreateBody } from "@lib/types/booking"; import AvatarGroup from "@components/ui/AvatarGroup"; import { Button } from "@components/ui/Button"; +import PhoneInput from "@components/ui/form/PhoneInput"; import { BookPageProps } from "../../../pages/[user]/book"; import { TeamBookingPageProps } from "../../../pages/team/[slug]/book"; @@ -37,7 +36,7 @@ import { TeamBookingPageProps } from "../../../pages/team/[slug]/book"; type BookingPageProps = BookPageProps | TeamBookingPageProps; const BookingPage = (props: BookingPageProps) => { - const { t } = useLocale({ localeProp: props.localeProp }); + const { t } = useLocale(); const router = useRouter(); const { rescheduleUid } = router.query; const { isReady } = useTheme(props.profile.theme); @@ -319,16 +318,7 @@ const BookingPage = (props: BookingPageProps) => { {t("phone_number")}
- { - /* DO NOT REMOVE: Callback required by PhoneInput, comment added to satisfy eslint:no-empty-function */ - }} - /> +
)} diff --git a/components/dialog/ConfirmationDialogContent.tsx b/components/dialog/ConfirmationDialogContent.tsx index 26d2dfe4..cdce27d8 100644 --- a/components/dialog/ConfirmationDialogContent.tsx +++ b/components/dialog/ConfirmationDialogContent.tsx @@ -9,7 +9,6 @@ import { DialogClose, DialogContent } from "@components/Dialog"; import { Button } from "@components/ui/Button"; export type ConfirmationDialogContentProps = { - localeProp: string; confirmBtnText?: string; cancelBtnText?: string; onConfirm?: (event: React.MouseEvent) => void; @@ -18,7 +17,7 @@ export type ConfirmationDialogContentProps = { }; export default function ConfirmationDialogContent(props: PropsWithChildren) { - const { t } = useLocale({ localeProp: props.localeProp }); + const { t } = useLocale(); const { title, variety, diff --git a/components/eventtype/EventTypeDescription.tsx b/components/eventtype/EventTypeDescription.tsx index 2df745ad..73e4d4b2 100644 --- a/components/eventtype/EventTypeDescription.tsx +++ b/components/eventtype/EventTypeDescription.tsx @@ -21,13 +21,12 @@ const eventTypeData = Prisma.validator()({ type EventType = Prisma.EventTypeGetPayload; export type EventTypeDescriptionProps = { - localeProp: string; eventType: EventType; className?: string; }; -export const EventTypeDescription = ({ localeProp, eventType, className }: EventTypeDescriptionProps) => { - const { t } = useLocale({ localeProp }); +export const EventTypeDescription = ({ eventType, className }: EventTypeDescriptionProps) => { + const { t } = useLocale(); return ( <> diff --git a/components/eventtype/EventTypeList.tsx b/components/eventtype/EventTypeList.tsx new file mode 100644 index 00000000..14d925f6 --- /dev/null +++ b/components/eventtype/EventTypeList.tsx @@ -0,0 +1,183 @@ +// TODO: replace headlessui with radix-ui +import { Menu, Transition } from "@headlessui/react"; +import { DotsHorizontalIcon, ExternalLinkIcon, LinkIcon } from "@heroicons/react/solid"; +import Link from "next/link"; +import React, { Fragment } from "react"; + +import classNames from "@lib/classNames"; +import { useLocale } from "@lib/hooks/useLocale"; +import showToast from "@lib/notification"; + +import { Tooltip } from "@components/Tooltip"; +import EventTypeDescription from "@components/eventtype/EventTypeDescription"; +import AvatarGroup from "@components/ui/AvatarGroup"; + +interface Props { + profile: { slug: string }; + readOnly: boolean; + types: { + $disabled: boolean; + hidden: boolean; + id: number; + slug: string; + title: string; + users: { + name: string; + avatar: string; + }[]; + }; +} + +const EventTypeList = ({ readOnly, types, profile }: Props): JSX.Element => { + const { t } = useLocale(); + return ( +
+
    + {types.map((type) => ( +
  • +
    +
    + + +
    + {type.title} + {type.hidden && ( + + {t("hidden")} + + )} + {readOnly && ( + + {t("readonly")} + + )} +
    + +
    + + +
    +
    + {type.users?.length > 1 && ( + ({ + alt: organizer.name || "", + image: organizer.avatar || "", + }))} + /> + )} + + + + + + + + + +
    +
    +
    +
    + + {({ open }) => ( + <> +
    + + {t("open_options")} + +
    + + + +
    + + {({ active }) => ( + + + )} + + + {({ active }) => ( + + )} + +
    +
    +
    + + )} +
    +
    +
    +
  • + ))} +
+
+ ); +}; + +export default EventTypeList; diff --git a/components/eventtype/EventTypeListHeading.tsx b/components/eventtype/EventTypeListHeading.tsx new file mode 100644 index 00000000..cbf4b884 --- /dev/null +++ b/components/eventtype/EventTypeListHeading.tsx @@ -0,0 +1,58 @@ +// TODO: replace headlessui with radix-ui +import { UsersIcon } from "@heroicons/react/solid"; +import Link from "next/link"; +import React from "react"; + +import Avatar from "@components/ui/Avatar"; +import Badge from "@components/ui/Badge"; + +interface Props { + profile: { + slug?: string | null; + name?: string | null; + image?: string | null; + }; + membershipCount: number; +} + +const EventTypeListHeading = ({ profile, membershipCount }: Props): JSX.Element => ( + +); + +export default EventTypeListHeading; diff --git a/components/security/ChangePasswordSection.tsx b/components/security/ChangePasswordSection.tsx index c9d05d3b..f64dc628 100644 --- a/components/security/ChangePasswordSection.tsx +++ b/components/security/ChangePasswordSection.tsx @@ -5,13 +5,13 @@ import { useLocale } from "@lib/hooks/useLocale"; import Modal from "@components/Modal"; -const ChangePasswordSection = ({ localeProp }: { localeProp: string }) => { +const ChangePasswordSection = () => { const [oldPassword, setOldPassword] = useState(""); const [newPassword, setNewPassword] = useState(""); const [successModalOpen, setSuccessModalOpen] = useState(false); const [errorMessage, setErrorMessage] = useState(null); const [isSubmitting, setIsSubmitting] = useState(false); - const { t } = useLocale({ localeProp }); + const { t } = useLocale(); const errorMessages: { [key: string]: string } = { [ErrorCode.IncorrectPassword]: t("current_incorrect_password"), diff --git a/components/security/DisableTwoFactorModal.tsx b/components/security/DisableTwoFactorModal.tsx index 813b4121..220069ff 100644 --- a/components/security/DisableTwoFactorModal.tsx +++ b/components/security/DisableTwoFactorModal.tsx @@ -10,23 +10,17 @@ import TwoFactorAuthAPI from "./TwoFactorAuthAPI"; import TwoFactorModalHeader from "./TwoFactorModalHeader"; interface DisableTwoFactorAuthModalProps { - /** - * Called when the user closes the modal without disabling two-factor auth - */ + /** Called when the user closes the modal without disabling two-factor auth */ onCancel: () => void; - - /** - * Called when the user disables two-factor auth - */ + /** Called when the user disables two-factor auth */ onDisable: () => void; - localeProp: string; } -const DisableTwoFactorAuthModal = ({ onDisable, onCancel, localeProp }: DisableTwoFactorAuthModalProps) => { +const DisableTwoFactorAuthModal = ({ onDisable, onCancel }: DisableTwoFactorAuthModalProps) => { const [password, setPassword] = useState(""); const [isDisabling, setIsDisabling] = useState(false); const [errorMessage, setErrorMessage] = useState(null); - const { t } = useLocale({ localeProp }); + const { t } = useLocale(); async function handleDisable(e: SyntheticEvent) { e.preventDefault(); diff --git a/components/security/EnableTwoFactorModal.tsx b/components/security/EnableTwoFactorModal.tsx index b77a357c..45b307b6 100644 --- a/components/security/EnableTwoFactorModal.tsx +++ b/components/security/EnableTwoFactorModal.tsx @@ -19,7 +19,6 @@ interface EnableTwoFactorModalProps { * Called when the user enables two-factor auth */ onEnable: () => void; - localeProp: string; } enum SetupStep { @@ -47,7 +46,7 @@ const WithStep = ({ return step === current ? children : null; }; -const EnableTwoFactorModal = ({ onEnable, onCancel, localeProp }: EnableTwoFactorModalProps) => { +const EnableTwoFactorModal = ({ onEnable, onCancel }: EnableTwoFactorModalProps) => { const [step, setStep] = useState(SetupStep.ConfirmPassword); const [password, setPassword] = useState(""); const [totpCode, setTotpCode] = useState(""); @@ -55,7 +54,7 @@ const EnableTwoFactorModal = ({ onEnable, onCancel, localeProp }: EnableTwoFacto const [secret, setSecret] = useState(""); const [isSubmitting, setIsSubmitting] = useState(false); const [errorMessage, setErrorMessage] = useState(null); - const { t } = useLocale({ localeProp }); + const { t } = useLocale(); async function handleSetup(e: SyntheticEvent) { e.preventDefault(); diff --git a/components/security/TwoFactorAuthSection.tsx b/components/security/TwoFactorAuthSection.tsx index afc95039..cc16c424 100644 --- a/components/security/TwoFactorAuthSection.tsx +++ b/components/security/TwoFactorAuthSection.tsx @@ -8,17 +8,11 @@ import Button from "@components/ui/Button"; import DisableTwoFactorModal from "./DisableTwoFactorModal"; import EnableTwoFactorModal from "./EnableTwoFactorModal"; -const TwoFactorAuthSection = ({ - twoFactorEnabled, - localeProp, -}: { - twoFactorEnabled: boolean; - localeProp: string; -}) => { +const TwoFactorAuthSection = ({ twoFactorEnabled }: { twoFactorEnabled: boolean }) => { const [enabled, setEnabled] = useState(twoFactorEnabled); const [enableModalOpen, setEnableModalOpen] = useState(false); const [disableModalOpen, setDisableModalOpen] = useState(false); - const { t, locale } = useLocale({ localeProp }); + const { t } = useLocale(); return ( <> @@ -39,7 +33,6 @@ const TwoFactorAuthSection = ({ {enableModalOpen && ( { setEnabled(true); setEnableModalOpen(false); @@ -50,7 +43,6 @@ const TwoFactorAuthSection = ({ {disableModalOpen && ( { setEnabled(false); setDisableModalOpen(false); diff --git a/components/team/EditTeam.tsx b/components/team/EditTeam.tsx index 886b8042..7e9bcf61 100644 --- a/components/team/EditTeam.tsx +++ b/components/team/EditTeam.tsx @@ -17,11 +17,7 @@ import ErrorAlert from "@components/ui/alerts/Error"; import MemberList from "./MemberList"; -export default function EditTeam(props: { - localeProp: string; - team: Team | undefined | null; - onCloseEdit: () => void; -}) { +export default function EditTeam(props: { team: Team | undefined | null; onCloseEdit: () => void }) { const [members, setMembers] = useState([]); const nameRef = useRef() as React.MutableRefObject; @@ -35,7 +31,7 @@ export default function EditTeam(props: { const [inviteModalTeam, setInviteModalTeam] = useState(); const [errorMessage, setErrorMessage] = useState(""); const [imageSrc, setImageSrc] = useState(""); - const { t, locale } = useLocale({ localeProp: props.localeProp }); + const { t } = useLocale(); const loadMembers = () => fetch("/api/teams/" + props.team?.id + "/membership") @@ -235,12 +231,7 @@ export default function EditTeam(props: {
{!!members.length && ( - + )}
@@ -278,7 +269,6 @@ export default function EditTeam(props: { {t("disband_team")} {showMemberInvitationModal && ( - + )} diff --git a/components/team/MemberInvitationModal.tsx b/components/team/MemberInvitationModal.tsx index 46daf30c..7fd6cd02 100644 --- a/components/team/MemberInvitationModal.tsx +++ b/components/team/MemberInvitationModal.tsx @@ -6,13 +6,9 @@ import { Team } from "@lib/team"; import Button from "@components/ui/Button"; -export default function MemberInvitationModal(props: { - localeProp: string; - team: Team | undefined | null; - onExit: () => void; -}) { +export default function MemberInvitationModal(props: { team: Team | undefined | null; onExit: () => void }) { const [errorMessage, setErrorMessage] = useState(""); - const { t } = useLocale({ localeProp: props.localeProp }); + const { t } = useLocale(); const handleError = async (res: Response) => { const responseData = await res.json(); diff --git a/components/team/MemberList.tsx b/components/team/MemberList.tsx index fd29d9f1..0099824c 100644 --- a/components/team/MemberList.tsx +++ b/components/team/MemberList.tsx @@ -1,16 +1,12 @@ -import { useLocale } from "@lib/hooks/useLocale"; import { Member } from "@lib/member"; import MemberListItem from "./MemberListItem"; export default function MemberList(props: { - localeProp: string; members: Member[]; onRemoveMember: (text: Member) => void; onChange: (text: string) => void; }) { - const { locale } = useLocale({ localeProp: props.localeProp }); - const selectAction = (action: string, member: Member) => { switch (action) { case "remove": @@ -24,7 +20,6 @@ export default function MemberList(props: {
    {props.members.map((member) => ( void; onChange: (text: string) => void; }) { const [member] = useState(props.member); - const { t, locale } = useLocale({ localeProp: props.localeProp }); + const { t } = useLocale(); return ( member && ( @@ -80,7 +79,6 @@ export default function MemberListItem(props: { void; onEditTeam: (text: Team) => void; }) { - const { locale } = useLocale({ localeProp: props.localeProp }); - const selectAction = (action: string, team: Team) => { switch (action) { case "edit": @@ -34,7 +30,6 @@ export default function TeamList(props: {
      {props.teams.map((team: Team) => ( void; key: number; team: Team; onActionSelect: (text: string) => void; }) { const [team, setTeam] = useState(props.team); - const { t, locale } = useLocale({ localeProp: props.localeProp }); + const { t } = useLocale(); const acceptInvite = () => invitationResponse(true); const declineInvite = () => invitationResponse(false); @@ -155,7 +154,6 @@ export default function TeamListItem(props: { { - const { t } = useLocale({ localeProp: localeProp }); +const Team = ({ team }) => { + const { t } = useLocale(); const Member = ({ member }) => { const classes = classnames( diff --git a/components/ui/TableActions.tsx b/components/ui/TableActions.tsx index cccb53d3..a2aff35d 100644 --- a/components/ui/TableActions.tsx +++ b/components/ui/TableActions.tsx @@ -7,7 +7,7 @@ import { SVGComponent } from "@lib/types/SVGComponent"; import Button from "./Button"; -type ActionType = { +export type ActionType = { id: string; icon: SVGComponent; label: string; diff --git a/components/ui/form/PhoneInput.tsx b/components/ui/form/PhoneInput.tsx index 357f55d6..d88f28d4 100644 --- a/components/ui/form/PhoneInput.tsx +++ b/components/ui/form/PhoneInput.tsx @@ -4,7 +4,7 @@ import "react-phone-number-input/style.css"; import classNames from "@lib/classNames"; -export const PhoneInput = (props) => ( +export const PhoneInput = (props: any /* FIXME */) => ( => { const session = await getSession({ req }); - const preferredLocale = parser.pick(i18n.locales, req.headers["accept-language"]) as Maybe; + const preferredLocale = getLocaleFromHeaders(req); if (session?.user?.id) { const user = await prisma.user.findUnique({ @@ -31,32 +31,17 @@ export const getOrSetUserLocaleFromHeaders = async (req: IncomingMessage): Promi return user.locale; } - if (preferredLocale) { - await prisma.user.update({ - where: { - id: session.user.id, - }, - data: { - locale: preferredLocale, - }, - }); - } else { - await prisma.user.update({ - where: { - id: session.user.id, - }, - data: { - locale: i18n.defaultLocale, - }, - }); - } + await prisma.user.update({ + where: { + id: session.user.id, + }, + data: { + locale: preferredLocale, + }, + }); } - if (preferredLocale) { - return preferredLocale; - } - - return i18n.defaultLocale; + return preferredLocale; }; interface localeType { diff --git a/lib/hooks/useLocale.ts b/lib/hooks/useLocale.ts index 832667c3..2fae0c7b 100644 --- a/lib/hooks/useLocale.ts +++ b/lib/hooks/useLocale.ts @@ -1,19 +1,10 @@ import { useTranslation } from "next-i18next"; -type LocaleProp = { - localeProp: string; -}; - -export const useLocale = (props: LocaleProp) => { +export const useLocale = () => { const { i18n, t } = useTranslation("common"); - if (i18n.language !== props.localeProp) { - i18n.changeLanguage(props.localeProp); - } - return { i18n, - locale: props.localeProp, t, }; }; diff --git a/pages/[user].tsx b/pages/[user].tsx index 4849cfde..7af16450 100644 --- a/pages/[user].tsx +++ b/pages/[user].tsx @@ -16,8 +16,8 @@ import Avatar from "@components/ui/Avatar"; export default function User(props: inferSSRProps) { const { isReady } = useTheme(props.user.theme); - const { user, localeProp, eventTypes } = props; - const { t, locale } = useLocale({ localeProp }); + const { user, eventTypes } = props; + const { t } = useLocale(); return ( <> @@ -50,7 +50,7 @@ export default function User(props: inferSSRProps) {

      {type.title}

      - +
      diff --git a/pages/_app.tsx b/pages/_app.tsx index a34869fe..a66ddec5 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -11,6 +11,8 @@ import superjson from "superjson"; import AppProviders from "@lib/app-providers"; import { seoConfig } from "@lib/config/next-seo.config"; +import I18nLanguageHandler from "@components/I18nLanguageHandler"; + import type { AppRouter } from "@server/routers/_app"; import "../styles/globals.css"; @@ -26,6 +28,7 @@ function MyApp(props: AppProps) { return ( + ); diff --git a/pages/event-types/[type].tsx b/pages/event-types/[type].tsx index ec6ed7fa..480959c9 100644 --- a/pages/event-types/[type].tsx +++ b/pages/event-types/[type].tsx @@ -85,7 +85,7 @@ const EventTypePage = (props: inferSSRProps) => { const { eventType, locationOptions, availability, team, teamMembers, hasPaymentIntegration, currency } = props; - const { t, locale } = useLocale({ localeProp: props.localeProp }); + const { t } = useLocale(); const router = useRouter(); const [successModalOpen, setSuccessModalOpen] = useState(false); @@ -992,7 +992,6 @@ const EventTypePage = (props: inferSSRProps) => { {t("delete")} ; -type EventType = PageProps["eventTypes"][number]; type Profile = PageProps["profiles"][number]; -type MembershipCount = EventType["metadata"]["membershipCount"]; const EventTypesPage = (props: PageProps) => { - const { t, locale } = useLocale({ localeProp: props.localeProp }); + const { t } = useLocale(); const CreateFirstEventTypeView = () => (
      @@ -63,218 +49,11 @@ const EventTypesPage = (props: PageProps) => {

      {t("new_event_type_heading")}

      {t("new_event_type_description")}

      - +
      ); - const EventTypeListHeading = ({ - profile, - membershipCount, - }: { - profile?: Profile; - membershipCount: MembershipCount; - }) => ( - - ); - - const EventTypeList = ({ - readOnly, - types, - profile, - }: { - profile: PageProps["profiles"][number]; - readOnly: boolean; - types: EventType["eventTypes"]; - }) => ( -
      -
        - {types.map((type) => ( -
      • -
        -
        - - -
        - {type.title} - {type.hidden && ( - - {t("hidden")} - - )} - {readOnly && ( - - {t("readonly")} - - )} -
        - -
        - - -
        -
        - {type.users?.length > 1 && ( - ({ - alt: organizer.name || "", - image: organizer.avatar || "", - }))} - /> - )} - - - - - - - - - -
        -
        -
        -
        - - {({ open }) => ( - <> -
        - - {t("open_options")} - -
        - - - -
        - - {({ active }) => ( - - - )} - - - {({ active }) => ( - - )} - -
        -
        -
        - - )} -
        -
        -
        -
      • - ))} -
      -
      - ); - return (
      @@ -328,19 +107,11 @@ const EventTypesPage = (props: PageProps) => { ); }; -const CreateNewEventDialog = ({ - profiles, - canAddEvents, - localeProp, -}: { - profiles: Profile[]; - canAddEvents: boolean; - localeProp: string; -}) => { +const CreateNewEventDialog = ({ profiles, canAddEvents }: { profiles: Profile[]; canAddEvents: boolean }) => { const router = useRouter(); const teamId: number | null = Number(router.query.teamId) || null; const modalOpen = useToggleQuery("new"); - const { t } = useLocale({ localeProp }); + const { t } = useLocale(); const createMutation = useMutation(createEventType, { onSuccess: async ({ eventType }) => { diff --git a/pages/settings/profile.tsx b/pages/settings/profile.tsx index ac4408f4..66698310 100644 --- a/pages/settings/profile.tsx +++ b/pages/settings/profile.tsx @@ -13,7 +13,6 @@ import { localeOptions, OptionType, } from "@lib/core/i18n/i18n.utils"; -import { useLocale } from "@lib/hooks/useLocale"; import { isBrandingHidden } from "@lib/isBrandingHidden"; import prisma from "@lib/prisma"; import { trpc } from "@lib/trpc"; @@ -92,7 +91,6 @@ function HideBrandingInput(props: { } export default function Settings(props: Props) { - const { locale } = useLocale({ localeProp: props.localeProp }); const mutation = trpc.useMutation("viewer.updateProfile"); const [successModalOpen, setSuccessModalOpen] = useState(false); @@ -101,14 +99,19 @@ export default function Settings(props: Props) { const descriptionRef = useRef(); const avatarRef = useRef(null); const hideBrandingRef = useRef(null); - const [selectedTheme, setSelectedTheme] = useState({ value: props.user.theme }); - const [selectedTimeZone, setSelectedTimeZone] = useState({ value: props.user.timeZone }); - const [selectedWeekStartDay, setSelectedWeekStartDay] = useState({ value: props.user.weekStart }); - const [selectedLanguage, setSelectedLanguage] = useState({ - value: locale, - label: props.localeLabels[locale], + const [selectedTheme, setSelectedTheme] = useState({ + value: props.user.theme, }); - const [imageSrc, setImageSrc] = useState(props.user.avatar); + const [selectedTimeZone, setSelectedTimeZone] = useState({ value: props.user.timeZone }); + const [selectedWeekStartDay, setSelectedWeekStartDay] = useState({ + value: props.user.weekStart, + label: "", + }); + const [selectedLanguage, setSelectedLanguage] = useState({ + value: props.localeProp, + label: props.localeLabels[props.localeProp], + }); + const [imageSrc, setImageSrc] = useState(props.user.avatar || ""); const [hasErrors, setHasErrors] = useState(false); const [errorMessage, setErrorMessage] = useState(""); @@ -117,7 +120,7 @@ export default function Settings(props: Props) { props.user.theme ? themeOptions.find((theme) => theme.value === props.user.theme) : null ); setSelectedWeekStartDay({ value: props.user.weekStart, label: props.user.weekStart }); - setSelectedLanguage({ value: locale, label: props.localeLabels[locale] }); + setSelectedLanguage({ value: props.localeProp, label: props.localeLabels[props.localeProp] }); }, []); const closeSuccessModal = () => { @@ -276,7 +279,7 @@ export default function Settings(props: Props) {