diff --git a/app/components/TimePopover.tsx b/app/components/TimePopover.tsx new file mode 100644 index 000000000..6affe59ff --- /dev/null +++ b/app/components/TimePopover.tsx @@ -0,0 +1,83 @@ +import { useRef, useState } from "react"; +import * as React from "react"; +import { Dialog } from "react-aria-components"; +import { Popover } from "react-aria-components"; +import { useTranslation } from "react-i18next"; +import { useCopyToClipboard } from "react-use"; +import { SendouButton } from "./elements/Button"; +import { CheckmarkIcon } from "./icons/Checkmark"; +import { ClipboardIcon } from "./icons/Clipboard"; + +export default function TimePopover({ + time, + options = { + minute: "numeric", + hour: "numeric", + day: "numeric", + month: "long", + }, +}: { + time: Date; + options?: Intl.DateTimeFormatOptions; +}) { + const { i18n } = useTranslation(); + + const [open, setOpen] = useState(false); + + const triggerRef = useRef(null); + + const { t } = useTranslation(["common"]); + + const [state, copyToClipboard] = useCopyToClipboard(); + const [copySuccess, setCopySuccess] = React.useState(false); + + React.useEffect(() => { + if (!state.value) return; + + setCopySuccess(true); + const timeout = setTimeout(() => setCopySuccess(false), 2000); + + return () => clearTimeout(timeout); + }, [state]); + + return ( +
+ + + +
+
+ {time.toLocaleTimeString(i18n.language, { + timeZoneName: "long", + hour: "numeric", + minute: "numeric", + })} +
+ copyToClipboard(``)} + icon={copySuccess ? : } + > + {t("common:actions.copyTimestampForDiscord")} + +
+
+
+
+ ); +} diff --git a/app/features/scrims/routes/scrims.$id.tsx b/app/features/scrims/routes/scrims.$id.tsx index 5c7e7af12..75dc5c4f2 100644 --- a/app/features/scrims/routes/scrims.$id.tsx +++ b/app/features/scrims/routes/scrims.$id.tsx @@ -15,6 +15,7 @@ import type { ScrimPost as ScrimPostType } from "../scrims-types"; import { loader } from "../loaders/scrims.$id.server"; export { loader }; +import TimePopover from "~/components/TimePopover"; import styles from "./scrims.$id.module.css"; export const handle: SendouRouteHandle = { @@ -50,19 +51,21 @@ export default function ScrimPage() { function ScrimHeader() { const { t } = useTranslation(["scrims"]); const data = useLoaderData(); - const { i18n } = useTranslation(); return (

- {databaseTimestampToDate(data.post.at).toLocaleString(i18n.language, { - weekday: "long", - year: "numeric", - month: "long", - day: "numeric", - hour: "numeric", - minute: "numeric", - })} +

{t("scrims:page.scheduledScrim")} diff --git a/app/features/tournament/routes/to.$id.register.tsx b/app/features/tournament/routes/to.$id.register.tsx index cf078f341..f18dc455f 100644 --- a/app/features/tournament/routes/to.$id.register.tsx +++ b/app/features/tournament/routes/to.$id.register.tsx @@ -59,6 +59,7 @@ import { } from "../tournament-utils"; import { useTournament } from "./to.$id"; +import TimePopover from "~/components/TimePopover"; import { action } from "../actions/to.$id.register.server"; import { loader } from "../loaders/to.$id.register.server"; export { loader, action }; @@ -66,7 +67,6 @@ export { loader, action }; export default function TournamentRegisterPage() { const user = useUser(); const isMounted = useIsMounted(); - const { i18n } = useTranslation(); const tournament = useTournament(); const startsAtEvenHour = tournament.ctx.startTime.getMinutes() === 0; @@ -123,15 +123,17 @@ export default function TournamentRegisterPage() {
{" "} - {isMounted - ? tournament.ctx.startTime.toLocaleString(i18n.language, { - timeZoneName: "short", + {isMounted ? ( + + ) : null}
) : null} diff --git a/app/styles/common.css b/app/styles/common.css index 913596e42..8d7e2c76b 100644 --- a/app/styles/common.css +++ b/app/styles/common.css @@ -252,6 +252,21 @@ details summary { user-select: none; } +.text-only-button { + cursor: pointer; + border: 0; + background-color: inherit; + color: inherit; + margin: 0; + padding: 0; +} + +.dotted { + text-decoration-style: dotted; + text-decoration-line: underline; + text-decoration-thickness: 2px; +} + .summary { border-radius: var(--rounded); background-color: var(--bg-darker-transparent); diff --git a/locales/de/common.json b/locales/de/common.json index dfd77b599..76fb728e5 100644 --- a/locales/de/common.json +++ b/locales/de/common.json @@ -99,6 +99,7 @@ "actions.showMore": "", "actions.showLess": "", "actions.copyToClipboard": "In die Zwischenablage kopieren", + "actions.copyTimestampForDiscord": "Discord-Zeitstempel kopieren", "actions.create": "Erstellen", "actions.close": "Schließen", "actions.cancel": "Abbrechen", diff --git a/locales/en/common.json b/locales/en/common.json index d31b4de10..2fea2a2b3 100644 --- a/locales/en/common.json +++ b/locales/en/common.json @@ -99,6 +99,7 @@ "actions.showMore": "Show more", "actions.showLess": "Show less", "actions.copyToClipboard": "Copy to clipboard", + "actions.copyTimestampForDiscord": "Copy Discord timestamp", "actions.create": "Create", "actions.close": "Close", "actions.cancel": "Cancel",