From d760bbaf1ad5dca620d6486abbc81eaa974e789a Mon Sep 17 00:00:00 2001 From: Chesterkxng Date: Wed, 25 Feb 2026 00:15:44 +0100 Subject: [PATCH] chore: - rewritten index file maching project architechture - sample examples added --- .../tools/time/discord-timestamp/index.tsx | 202 +++++++++++++----- 1 file changed, 143 insertions(+), 59 deletions(-) diff --git a/src/pages/tools/time/discord-timestamp/index.tsx b/src/pages/tools/time/discord-timestamp/index.tsx index c0ee38e..e33e69a 100644 --- a/src/pages/tools/time/discord-timestamp/index.tsx +++ b/src/pages/tools/time/discord-timestamp/index.tsx @@ -1,72 +1,156 @@ -import { useState } from 'react'; +import { Box } from '@mui/material'; +import React, { useState } from 'react'; +import ToolContent from '@components/ToolContent'; +import { ToolComponentProps } from '@tools/defineTool'; +import ToolTextInput from '@components/input/ToolTextInput'; +import ToolTextResult from '@components/result/ToolTextResult'; +import { GetGroupsType } from '@components/options/ToolOptions'; +import { CardExampleType } from '@components/examples/ToolExamples'; +import SelectWithDesc from '@components/options/SelectWithDesc'; +import CheckboxWithDesc from '@components/options/CheckboxWithDesc'; +import { DiscordTimestampGenerator } from './service'; +import { useTranslation } from 'react-i18next'; +import { DiscordTimestampFormat, InitialValuesType } from './types'; -function convertInput(input: string) { - const trimmed = input.trim(); +const initialValues: InitialValuesType = { + format: 'F', + enforceUTC: true +}; - // Case 1: Discord timestamp → normal date - const match = trimmed.match(/^$/); - if (match) { - const unix = Number(match[1]); - const date = new Date(unix * 1000); - if (!isNaN(date.getTime())) { - return date.toISOString().replace('T', ' ').slice(0, 16); +const exampleCards: CardExampleType[] = [ + { + title: 'Convert a single datetime', + description: + "In this example, we convert a single datetime into a Discord timestamp using the Long Date & Time format (F). The input is an ISO 8601 datetime string and the output is a Discord timestamp that will display the full date and time in each viewer's local timezone.", + sampleText: `2025-03-15T10:00:00`, + sampleResult: ``, + sampleOptions: { + ...initialValues, + format: 'F' + } + }, + { + title: 'Convert multiple datetimes', + description: + 'In this example, we convert multiple datetimes at once — one per line. Blank lines are preserved in the output. Each valid datetime is converted to a Discord timestamp using the Short Date & Time format (f).', + sampleText: `2025-03-15T10:00:00 +2025-07-20T18:45:00 + +2025-11-05T08:15:00`, + sampleResult: ` + + +`, + sampleOptions: { + ...initialValues, + format: 'f' + } + }, + { + title: 'Relative timestamps', + description: + 'In this example, we use the Relative format (R) which displays how long ago or how far in the future a datetime is — for example "2 hours ago" or "in 3 days". This format is useful for countdowns or activity feeds and updates dynamically in Discord.', + sampleText: `2025-03-15T10:00:00 +2025-07-20T18:45:00 +2025-11-05T08:15:00`, + sampleResult: ` + +`, + sampleOptions: { + ...initialValues, + format: 'R' } } +]; - // Case 2: normal date → Discord timestamp - const date = new Date(trimmed); - if (isNaN(date.getTime())) return 'Invalid date/time'; - const unix = Math.floor(date.getTime() / 1000); - return ``; -} +type formatProps = { + label: string; + value: DiscordTimestampFormat; +}; -export default function DiscordTimestamp() { - const [value, setValue] = useState(''); - const [copied, setCopied] = useState(false); +export default function TruncateClockTime({ + title, + longDescription +}: ToolComponentProps) { + const { t } = useTranslation('time'); + const [input, setInput] = useState(''); + const [result, setResult] = useState(''); - const result = value ? convertInput(value) : ''; - - const handleCopy = async () => { - if (!result || result === 'Invalid date/time') return; - try { - await navigator.clipboard.writeText(result); - setCopied(true); - setTimeout(() => setCopied(false), 1200); - } catch (e) { - console.error('Copy failed', e); - } + const compute = (optionsValues: InitialValuesType, input: string) => { + setResult(DiscordTimestampGenerator(input, optionsValues)); }; + const FORMATS: formatProps[] = [ + { label: t('discordTimestamp.formats.short_time'), value: 't' }, + { label: t('discordTimestamp.formats.long_time'), value: 'T' }, + { label: t('discordTimestamp.formats.short_date'), value: 'd' }, + { label: t('discordTimestamp.formats.long_date'), value: 'D' }, + { label: t('discordTimestamp.formats.short_datetime'), value: 'f' }, + { label: t('discordTimestamp.formats.long_datetime'), value: 'F' }, + { label: t('discordTimestamp.formats.relative'), value: 'R' } + ]; + + const getGroups: GetGroupsType | null = ({ + values, + updateField + }) => [ + { + title: t('discordTimestamp.utc.title'), + component: ( + + updateField('enforceUTC', value)} + title={t('discordTimestamp.utc.label')} + description={t('discordTimestamp.utc.description')} + /> + + ) + }, + { + title: t('discordTimestamp.formats.title'), + component: ( + + updateField('format', value)} + options={FORMATS.map((format) => ({ + label: format.label, + value: format.value + }))} + description={t('discordTimestamp.formats.description')} + /> + + ) + } + ]; + return ( -
-