+
+
+
{t('localization.description')}
+
+
{t('localization.language')}
+
- {t('localization.description')}
+ {t('localization.languageDescription')}
-
-
-
-
-
-
- {t('localization.language')}
-
-
-
- {t('localization.languageDescription')}
-
-
-
- {isRTL && (
-
- This language uses right-to-left (RTL) text direction
-
+
+
+ {isRTL && (
+
+ {t(
+ 'localization.rtlNotice',
+ 'This language uses right-to-left (RTL) text direction',
)}
-
-
+
+ )}
+
-
+ {t('localization.dateFormat')}
+
+
+ {t('localization.dateFormatDescription')}
+
+
+
+
+ Preview: {sampleDate.format(dateFormat)}
+
+
-
-
- {t('localization.dateFormat')}
-
-
- {t('localization.dateFormatDescription')}
-
-
-
-
-
-
-
-
- {t('localization.timeFormat')}
-
-
- {t('localization.timeFormatDescription')}
-
-
- setTimeFormat(value)}
- sx={{ minWidth: 250 }}
- >
-
-
- {t('localization.12hour')}
-
- {sampleDate.format(TIME_FORMATS.HOUR_12)}
-
-
-
-
-
- {t('localization.24hour')}
-
- {sampleDate.format(TIME_FORMATS.HOUR_24)}
-
-
-
-
-
- Preview: {sampleDate.format(timeFormat)}
-
-
-
-
-
-
-
-
- {t('localization.firstDayOfWeek')}
-
-
- {t('localization.firstDayOfWeekDescription')}
-
-
-
-
-
-
+ {t('localization.12hour')}
+
+ {sampleDate.format(TIME_FORMATS.HOUR_12)}
+
-
-
-
+
+
+
+ {t('localization.24hour')}
+
+ {sampleDate.format(TIME_FORMATS.HOUR_24)}
+
+
+
+
+
+ Preview: {sampleDate.format(timeFormat)}
+
+
+
+
{t('localization.firstDayOfWeek')}
+
+
+ {t('localization.firstDayOfWeekDescription')}
+
+
+
+
+
+
+
+
)
diff --git a/src/views/Settings/Settings.jsx b/src/views/Settings/Settings.jsx
index 52c8172..c1e66bc 100644
--- a/src/views/Settings/Settings.jsx
+++ b/src/views/Settings/Settings.jsx
@@ -60,7 +60,7 @@ const Settings = () => {
const queryClient = useQueryClient()
const { showNotification } = useNotification()
const navigate = useNavigate()
- const { formatDate } = useLocalization()
+ const { fmt } = useLocalization()
const [userCircles, setUserCircles] = useState([])
const [circleMemberRequests, setCircleMemberRequests] = useState([])
@@ -191,11 +191,11 @@ const Settings = () => {
const getSubscriptionDetails = () => {
if (userProfile?.subscription === 'active') {
- return `You are currently subscribed to the Plus plan. Your subscription will renew on ${formatDate(
+ return `You are currently subscribed to the Plus plan. Your subscription will renew on ${fmt.date(
userProfile?.expiration,
)}.`
} else if (userProfile?.subscription === 'cancelled') {
- return `You have cancelled your subscription. Your account will be downgraded to the Free plan on ${formatDate(
+ return `You have cancelled your subscription. Your account will be downgraded to the Free plan on ${fmt.date(
userProfile?.expiration,
)}.`
} else {
@@ -207,7 +207,7 @@ const Settings = () => {
return `Plus`
} else if (userProfile?.subscription === 'cancelled') {
if (moment().isBefore(userProfile?.expiration)) {
- return `Plus(until ${formatDate(userProfile?.expiration)})`
+ return `Plus(until ${fmt.date(userProfile?.expiration)})`
}
return `Free`
} else {
@@ -340,12 +340,12 @@ const Settings = () => {
{member.isActive ? (
- Joined on {moment(member.createdAt).format('MMM DD, YYYY')}
+ Joined on {fmt.date(member.createdAt)}
) : (
Request to join{' '}
- {moment(member.updatedAt).format('MMM DD, YYYY')}
+ {fmt.date(member.updatedAt)}
)}
@@ -486,7 +486,7 @@ const Settings = () => {
{lastRefresh && (
- Last updated: {moment(lastRefresh).format('MMM DD, HH:mm')}
+ Last updated: {fmt.dateTime(lastRefresh)}
)}
@@ -316,12 +324,33 @@ const SettingsOverview = () => {
-
- {setting.title}
-
+
+ {setting.title}
+
+ {setting.isBeta && (
+
+ Early Access
+
+ )}
+
{
const { id } = useParams()
const theme = useTheme()
+ const { fmt } = useLocalization()
const {
data,
error,
@@ -294,9 +296,7 @@ const ThingsHistory = () => {
tick='false'
tickLine='false'
axisLine='false'
- tickFormatter={tick =>
- moment(tick).format('ddd MM/DD/yyyy HH:mm:ss')
- }
+ tickFormatter={tick => fmt.dateTime(tick)}
/>
{
axisLine='false'
/>
- moment(label).format('ddd MM/DD/yyyy HH:mm:ss')
- }
+ labelFormatter={label => fmt.dateTime(label)}
/>
{
color='primary'
startDecorator={}
>
- {moment(history.updatedAt).format('MMM DD, h:mm A')}
+ {fmt.dateTime(history.updatedAt)}
diff --git a/src/views/Timer/TimerDetails.jsx b/src/views/Timer/TimerDetails.jsx
index 9a60f58..349e15b 100644
--- a/src/views/Timer/TimerDetails.jsx
+++ b/src/views/Timer/TimerDetails.jsx
@@ -38,6 +38,7 @@ import {
import moment from 'moment'
import { useEffect, useState } from 'react'
import { useParams } from 'react-router-dom'
+import { useLocalization } from '../../contexts/LocalizationContext'
import {
useChoreTimer,
usePauseChore,
@@ -52,6 +53,7 @@ import LoadingComponent from '../components/Loading'
const TimerDetails = () => {
const { choreId } = useParams()
+ const { fmt } = useLocalization()
const [timerData, setTimerData] = useState(null)
const [loading, setLoading] = useState(false)
const [editingSessions, setEditingSessions] = useState({})
@@ -819,14 +821,14 @@ const TimerDetails = () => {
level='body-xs'
sx={{ color: 'text.tertiary' }}
>
- Started: {moment(timerData.startTime).format('HH:mm')}
+ Started: {fmt.time(timerData.startTime)}
{timerData.endTime && (
- Ended: {moment(timerData.endTime).format('HH:mm')}
+ Ended: {fmt.time(timerData.endTime)}
)}
{!timerData.endTime && (
@@ -834,7 +836,7 @@ const TimerDetails = () => {
level='body-xs'
sx={{ color: 'success.500' }}
>
- Now: {moment(currentTime).format('HH:mm')}
+ Now: {fmt.time(currentTime)}
)}
{
const sessionDate = moment(pause.start).format(
'MMM DD',
)
- const startTime = moment(pause.start).format('HH:mm')
+ const startTime = fmt.time(pause.start)
const endTime = pause.end
- ? moment(pause.end).format('HH:mm')
+ ? fmt.time(pause.end)
: null
const realTimeDuration = isOngoing
diff --git a/src/views/User/UserActivities.jsx b/src/views/User/UserActivities.jsx
index 7a76eef..14baf15 100644
--- a/src/views/User/UserActivities.jsx
+++ b/src/views/User/UserActivities.jsx
@@ -32,6 +32,7 @@ import {
} from '@mui/joy'
import React, { useEffect, useState } from 'react'
+import { useLocalization } from '../../contexts/LocalizationContext'
import { useChores, useChoresHistory } from '../../queries/ChoreQueries'
import { useCircleMembers, useUserProfile } from '../../queries/UserQueries.jsx'
import { ChoresGrouper } from '../../utils/Chores'
@@ -119,6 +120,7 @@ const ChoreHistoryItem = ({ time, name, points, status, performer }) => {
}
const ChoreHistoryTimeline = ({ history }) => {
+ const { fmt } = useLocalization()
const groupedHistory = groupByDate(history)
return (
@@ -133,12 +135,7 @@ const ChoreHistoryTimeline = ({ history }) => {
{Object.entries(groupedHistory).map(([date, items]) => (
- {new Date(date).toLocaleDateString([], {
- weekday: 'long',
- month: 'long',
- day: 'numeric',
- year: 'numeric',
- })}
+ {fmt.date(date)}
@@ -146,10 +143,7 @@ const ChoreHistoryTimeline = ({ history }) => {
<>
{
}
const CalendarCard = ({ chores }) => {
const { data: userProfile } = useUserProfile()
+ const { fmt } = useLocalization()
const [selectedDate, setSeletedDate] = useState(null)
const Navigate = useNavigate()
@@ -197,7 +199,7 @@ const CalendarCard = ({ chores }) => {
}}
>
- {moment(selectedDate).format('MMMM D, YYYY')}
+ {fmt.date(selectedDate)}
{(() => {
@@ -291,7 +293,7 @@ const CalendarCard = ({ chores }) => {
color: 'neutral.500',
}}
>
- {moment(chore.nextDueDate).format('h:mm A')}
+ {fmt.time(chore.nextDueDate)}
{/* {
}
const CalendarDual = ({ chores, onDateChange }) => {
const { data: userProfile } = useUserProfile()
- const { firstDayOfWeek } = useLocalization()
+ const { firstDayOfWeek, fmt } = useLocalization()
const calendarType =
firstDayOfWeek === 1 ? 'iso8601' : firstDayOfWeek === 6 ? 'islamic' : 'gregory'
@@ -100,10 +100,7 @@ const CalendarDual = ({ chores, onDateChange }) => {
{isSecondary && (
- {date.toLocaleDateString('en-US', {
- month: 'long',
- year: 'numeric',
- })}
+ {fmt.date(date, 'MMMM YYYY')}
)}
diff --git a/src/views/components/SubTask.jsx b/src/views/components/SubTask.jsx
index 5f238aa..01a505f 100644
--- a/src/views/components/SubTask.jsx
+++ b/src/views/components/SubTask.jsx
@@ -32,6 +32,7 @@ import {
Typography,
} from '@mui/joy'
import { useState } from 'react'
+import { useLocalization } from '../../contexts/LocalizationContext'
import { useImpersonateUser } from '../../contexts/ImpersonateUserContext'
import { useUserProfile } from '../../queries/UserQueries'
import { CompleteSubTask } from '../../utils/Fetcher'
@@ -48,6 +49,7 @@ function SortableItem({
editMode,
performers = [],
}) {
+ const { fmt } = useLocalization()
const { attributes, listeners, setNodeRef, transform, transition } =
useSortable({
id: task.id,
@@ -210,7 +212,7 @@ function SortableItem({
fontSize: 'sm',
}}
>
- {new Date(task.completedAt).toLocaleString()}
+ {fmt.dateTime(task.completedAt)}
{performers.find(p => p.userId === task.completedBy) ? (
{