From fcbccbc838ab48febd500b63b3e0398d48805501 Mon Sep 17 00:00:00 2001 From: Chris Date: Wed, 17 Sep 2025 16:56:50 +0300 Subject: [PATCH] Feat add first day of week (#339) * Add setup for first day of week * Add full weekdays * fixup! Add full weekdays --- ...16000000-add-first-day-of-week-to-users.js | 26 ++++ backend/models/user.js | 9 ++ backend/routes/users.js | 18 +++ .../components/Calendar/CalendarMonthView.tsx | 46 +++++- .../components/Calendar/CalendarWeekView.tsx | 32 +++- .../components/Profile/ProfileSettings.tsx | 32 ++++ frontend/components/Shared/DatePicker.tsx | 40 ++++- .../Shared/FirstDayOfWeekDropdown.tsx | 137 ++++++++++++++++++ frontend/utils/profileService.ts | 81 +++++++++++ public/locales/bg/translation.json | 12 +- public/locales/da/translation.json | 12 +- public/locales/de/translation.json | 12 +- public/locales/el/translation.json | 12 +- public/locales/en/translation.json | 10 ++ public/locales/es/translation.json | 12 +- public/locales/fi/translation.json | 12 +- public/locales/fr/translation.json | 12 +- public/locales/id/translation.json | 12 +- public/locales/it/translation.json | 12 +- public/locales/jp/translation.json | 12 +- public/locales/ko/translation.json | 12 +- public/locales/nl/translation.json | 12 +- public/locales/no/translation.json | 12 +- public/locales/pl/translation.json | 12 +- public/locales/pt/translation.json | 12 +- public/locales/ro/translation.json | 12 +- public/locales/ru/translation.json | 12 +- public/locales/sl/translation.json | 12 +- public/locales/sv/translation.json | 12 +- public/locales/tr/translation.json | 12 +- public/locales/ua/translation.json | 12 +- public/locales/vi/translation.json | 12 +- public/locales/zh/translation.json | 12 +- 33 files changed, 673 insertions(+), 34 deletions(-) create mode 100644 backend/migrations/20250116000000-add-first-day-of-week-to-users.js create mode 100644 frontend/components/Shared/FirstDayOfWeekDropdown.tsx diff --git a/backend/migrations/20250116000000-add-first-day-of-week-to-users.js b/backend/migrations/20250116000000-add-first-day-of-week-to-users.js new file mode 100644 index 0000000..26fae4e --- /dev/null +++ b/backend/migrations/20250116000000-add-first-day-of-week-to-users.js @@ -0,0 +1,26 @@ +'use strict'; + +const { safeAddColumns } = require('../utils/migration-utils'); + +module.exports = { + async up(queryInterface, Sequelize) { + await safeAddColumns(queryInterface, 'users', [ + { + name: 'first_day_of_week', + definition: { + type: Sequelize.INTEGER, + allowNull: false, + defaultValue: 1, // Monday by default + validate: { + min: 0, // Sunday + max: 6, // Saturday + }, + }, + }, + ]); + }, + + async down(queryInterface) { + await queryInterface.removeColumn('users', 'first_day_of_week'); + }, +}; diff --git a/backend/models/user.js b/backend/models/user.js index 71187f3..128d502 100644 --- a/backend/models/user.js +++ b/backend/models/user.js @@ -49,6 +49,15 @@ module.exports = (sequelize) => { allowNull: false, defaultValue: 'UTC', }, + first_day_of_week: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: 1, // Monday by default + validate: { + min: 0, // Sunday + max: 6, // Saturday + }, + }, avatar_image: { type: DataTypes.STRING, allowNull: true, diff --git a/backend/routes/users.js b/backend/routes/users.js index 7609b16..5b97fbf 100644 --- a/backend/routes/users.js +++ b/backend/routes/users.js @@ -28,6 +28,7 @@ router.get('/profile', async (req, res) => { 'appearance', 'language', 'timezone', + 'first_day_of_week', 'avatar_image', 'telegram_bot_token', 'telegram_chat_id', @@ -80,6 +81,7 @@ router.patch('/profile', async (req, res) => { appearance, language, timezone, + first_day_of_week, avatar_image, telegram_bot_token, telegram_allowed_users, @@ -98,6 +100,8 @@ router.patch('/profile', async (req, res) => { if (appearance !== undefined) allowedUpdates.appearance = appearance; if (language !== undefined) allowedUpdates.language = language; if (timezone !== undefined) allowedUpdates.timezone = timezone; + if (first_day_of_week !== undefined) + allowedUpdates.first_day_of_week = first_day_of_week; if (avatar_image !== undefined) allowedUpdates.avatar_image = avatar_image; if (telegram_bot_token !== undefined) @@ -123,6 +127,20 @@ router.patch('/profile', async (req, res) => { if (pomodoro_enabled !== undefined) allowedUpdates.pomodoro_enabled = pomodoro_enabled; + // Validate first_day_of_week if provided + if (first_day_of_week !== undefined) { + if ( + typeof first_day_of_week !== 'number' || + first_day_of_week < 0 || + first_day_of_week > 6 + ) { + return res.status(400).json({ + field: 'first_day_of_week', + error: 'First day of week must be a number between 0 (Sunday) and 6 (Saturday)', + }); + } + } + // Handle password change if provided if (currentPassword && newPassword) { if (newPassword.length < 6) { diff --git a/frontend/components/Calendar/CalendarMonthView.tsx b/frontend/components/Calendar/CalendarMonthView.tsx index ba90f6f..7d07e0e 100644 --- a/frontend/components/Calendar/CalendarMonthView.tsx +++ b/frontend/components/Calendar/CalendarMonthView.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useState, useEffect } from 'react'; import { format, startOfMonth, @@ -10,6 +10,10 @@ import { endOfWeek, } from 'date-fns'; import { useTranslation } from 'react-i18next'; +import { + getFirstDayOfWeek, + getLocaleFirstDayOfWeek, +} from '../../utils/profileService'; interface CalendarEvent { id: string; @@ -34,27 +38,59 @@ const CalendarMonthView: React.FC = ({ onEventClick, }) => { const { t } = useTranslation(); + const [firstDayOfWeek, setFirstDayOfWeek] = useState(1); // Default to Monday + + // Load first day of week setting + useEffect(() => { + const loadFirstDayOfWeek = async () => { + try { + const firstDay = await getFirstDayOfWeek(); + setFirstDayOfWeek(firstDay); + } catch { + const fallbackFirstDay = getLocaleFirstDayOfWeek( + navigator.language + ); + setFirstDayOfWeek(fallbackFirstDay); + } + }; + loadFirstDayOfWeek(); + }, []); const monthStart = startOfMonth(currentDate); const monthEnd = endOfMonth(currentDate); - const calendarStart = startOfWeek(monthStart, { weekStartsOn: 1 }); // Start on Monday - const calendarEnd = endOfWeek(monthEnd, { weekStartsOn: 1 }); + const calendarStart = startOfWeek(monthStart, { + weekStartsOn: firstDayOfWeek as 0 | 1 | 2 | 3 | 4 | 5 | 6, + }); + const calendarEnd = endOfWeek(monthEnd, { + weekStartsOn: firstDayOfWeek as 0 | 1 | 2 | 3 | 4 | 5 | 6, + }); const days = eachDayOfInterval({ start: calendarStart, end: calendarEnd, }); - const weekDays = [ + // Generate weekdays array based on first day of week setting + const getAllWeekDays = () => [ + t('weekdays.sunday', 'Sun'), t('weekdays.monday', 'Mon'), t('weekdays.tuesday', 'Tue'), t('weekdays.wednesday', 'Wed'), t('weekdays.thursday', 'Thu'), t('weekdays.friday', 'Fri'), t('weekdays.saturday', 'Sat'), - t('weekdays.sunday', 'Sun'), ]; + const getWeekDays = () => { + const allDays = getAllWeekDays(); + return [ + ...allDays.slice(firstDayOfWeek), + ...allDays.slice(0, firstDayOfWeek), + ]; + }; + + const weekDays = getWeekDays(); + const handleDateClick = (date: Date) => { if (onDateClick) { onDateClick(date); diff --git a/frontend/components/Calendar/CalendarWeekView.tsx b/frontend/components/Calendar/CalendarWeekView.tsx index 0392601..88e89e2 100644 --- a/frontend/components/Calendar/CalendarWeekView.tsx +++ b/frontend/components/Calendar/CalendarWeekView.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useState, useEffect } from 'react'; import { format, startOfWeek, @@ -7,6 +7,10 @@ import { isToday, addHours, } from 'date-fns'; +import { + getFirstDayOfWeek, + getLocaleFirstDayOfWeek, +} from '../../utils/profileService'; interface CalendarEvent { id: string; @@ -31,8 +35,30 @@ const CalendarWeekView: React.FC = ({ onEventClick, onTimeSlotClick, }) => { - const weekStart = startOfWeek(currentDate, { weekStartsOn: 1 }); - const weekEnd = endOfWeek(currentDate, { weekStartsOn: 1 }); + const [firstDayOfWeek, setFirstDayOfWeek] = useState(1); // Default to Monday + + // Load first day of week setting + useEffect(() => { + const loadFirstDayOfWeek = async () => { + try { + const firstDay = await getFirstDayOfWeek(); + setFirstDayOfWeek(firstDay); + } catch { + const fallbackFirstDay = getLocaleFirstDayOfWeek( + navigator.language + ); + setFirstDayOfWeek(fallbackFirstDay); + } + }; + loadFirstDayOfWeek(); + }, []); + + const weekStart = startOfWeek(currentDate, { + weekStartsOn: firstDayOfWeek as 0 | 1 | 2 | 3 | 4 | 5 | 6, + }); + const weekEnd = endOfWeek(currentDate, { + weekStartsOn: firstDayOfWeek as 0 | 1 | 2 | 3 | 4 | 5 | 6, + }); const weekDays = eachDayOfInterval({ start: weekStart, end: weekEnd }); const hours = Array.from({ length: 24 }, (_, i) => i); diff --git a/frontend/components/Profile/ProfileSettings.tsx b/frontend/components/Profile/ProfileSettings.tsx index 127a5d3..b8a805f 100644 --- a/frontend/components/Profile/ProfileSettings.tsx +++ b/frontend/components/Profile/ProfileSettings.tsx @@ -28,6 +28,8 @@ import TelegramIcon from '../Icons/TelegramIcon'; import { useToast } from '../Shared/ToastContext'; import { dispatchTelegramStatusChange } from '../../contexts/TelegramStatusContext'; import LanguageDropdown from '../Shared/LanguageDropdown'; +import FirstDayOfWeekDropdown from '../Shared/FirstDayOfWeekDropdown'; +import { getLocaleFirstDayOfWeek } from '../../utils/profileService'; interface ProfileSettingsProps { currentUser: { id: number; email: string }; @@ -41,6 +43,7 @@ interface Profile { appearance: 'light' | 'dark'; language: string; timezone: string; + first_day_of_week: number; avatar_image: string | null; telegram_bot_token: string | null; telegram_chat_id: string | null; @@ -102,6 +105,7 @@ const ProfileSettings: React.FC = ({ appearance: isDarkMode ? 'dark' : 'light', language: 'en', timezone: 'UTC', + first_day_of_week: 1, // Monday by default avatar_image: '', telegram_bot_token: '', telegram_allowed_users: '', @@ -259,6 +263,10 @@ const ProfileSettings: React.FC = ({ data.appearance || (isDarkMode ? 'dark' : 'light'), language: data.language || 'en', timezone: data.timezone || 'UTC', + first_day_of_week: + data.first_day_of_week !== undefined + ? data.first_day_of_week + : 1, avatar_image: data.avatar_image || '', telegram_bot_token: data.telegram_bot_token || '', telegram_allowed_users: data.telegram_allowed_users || '', @@ -888,9 +896,15 @@ const ProfileSettings: React.FC = ({ { + // Auto-set first day of week based on language/locale + const localeFirstDay = + getLocaleFirstDayOfWeek( + languageCode + ); setFormData((prev) => ({ ...prev, language: languageCode, + first_day_of_week: localeFirstDay, })); }} /> @@ -1153,6 +1167,24 @@ const ProfileSettings: React.FC = ({ + +
+ + { + setFormData((prev) => ({ + ...prev, + first_day_of_week: value, + })); + }} + /> +
)} diff --git a/frontend/components/Shared/DatePicker.tsx b/frontend/components/Shared/DatePicker.tsx index 7dc65d5..f3ea72f 100644 --- a/frontend/components/Shared/DatePicker.tsx +++ b/frontend/components/Shared/DatePicker.tsx @@ -5,6 +5,10 @@ import { ChevronRightIcon, CalendarDaysIcon, } from '@heroicons/react/24/outline'; +import { + getFirstDayOfWeek, + getLocaleFirstDayOfWeek, +} from '../../utils/profileService'; interface DatePickerProps { value: string; @@ -29,6 +33,7 @@ const DatePicker: React.FC = ({ openUpward: false, }); const [currentMonth, setCurrentMonth] = useState(new Date()); + const [firstDayOfWeek, setFirstDayOfWeek] = useState(0); // 0 = Sunday, 1 = Monday, etc. const dropdownRef = useRef(null); const menuRef = useRef(null); @@ -47,7 +52,15 @@ const DatePicker: React.FC = ({ 'December', ]; - const days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; + // Generate days array based on first day of week setting + const getAllDays = () => ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; + const getDaysOfWeek = () => { + const allDays = getAllDays(); + return [ + ...allDays.slice(firstDayOfWeek), + ...allDays.slice(0, firstDayOfWeek), + ]; + }; const formatDate = (date: Date) => { const year = date.getFullYear(); @@ -187,10 +200,14 @@ const DatePicker: React.FC = ({ const daysInMonth = lastDay.getDate(); const startingDayOfWeek = firstDay.getDay(); + // Adjust starting day based on first day of week setting + const adjustedStartingDay = + (startingDayOfWeek - firstDayOfWeek + 7) % 7; + const days = []; // Add empty cells for days before the first day of the month - for (let i = 0; i < startingDayOfWeek; i++) { + for (let i = 0; i < adjustedStartingDay; i++) { days.push(null); } @@ -215,6 +232,23 @@ const DatePicker: React.FC = ({ ); }; + // Load first day of week setting on mount + useEffect(() => { + const loadFirstDayOfWeek = async () => { + try { + const firstDay = await getFirstDayOfWeek(); + setFirstDayOfWeek(firstDay); + } catch { + // Fallback to locale-based default + const fallbackFirstDay = getLocaleFirstDayOfWeek( + navigator.language + ); + setFirstDayOfWeek(fallbackFirstDay); + } + }; + loadFirstDayOfWeek(); + }, []); + useEffect(() => { if (isOpen) { document.addEventListener('mousedown', handleClickOutside); @@ -305,7 +339,7 @@ const DatePicker: React.FC = ({
{/* Day Headers */}
- {days.map((day) => ( + {getDaysOfWeek().map((day) => (
void; + className?: string; +} + +const FirstDayOfWeekDropdown: React.FC = ({ + value, + onChange, + className = '', +}) => { + const { t } = useTranslation(); + const [isOpen, setIsOpen] = useState(false); + const dropdownRef = useRef(null); + + const weekdays: WeekdayOption[] = [ + { + value: 0, + label: t('weekdaysFull.sunday', 'Sunday'), + translationKey: 'weekdaysFull.sunday', + }, + { + value: 1, + label: t('weekdaysFull.monday', 'Monday'), + translationKey: 'weekdaysFull.monday', + }, + { + value: 2, + label: t('weekdaysFull.tuesday', 'Tuesday'), + translationKey: 'weekdaysFull.tuesday', + }, + { + value: 3, + label: t('weekdaysFull.wednesday', 'Wednesday'), + translationKey: 'weekdaysFull.wednesday', + }, + { + value: 4, + label: t('weekdaysFull.thursday', 'Thursday'), + translationKey: 'weekdaysFull.thursday', + }, + { + value: 5, + label: t('weekdaysFull.friday', 'Friday'), + translationKey: 'weekdaysFull.friday', + }, + { + value: 6, + label: t('weekdaysFull.saturday', 'Saturday'), + translationKey: 'weekdaysFull.saturday', + }, + ]; + + const selectedWeekday = + weekdays.find((day) => day.value === value) || weekdays[1]; // Default to Monday + + useEffect(() => { + const handleClickOutside = (event: MouseEvent) => { + if ( + dropdownRef.current && + !dropdownRef.current.contains(event.target as Node) + ) { + setIsOpen(false); + } + }; + + document.addEventListener('mousedown', handleClickOutside); + return () => + document.removeEventListener('mousedown', handleClickOutside); + }, []); + + const handleSelect = (weekday: WeekdayOption) => { + onChange(weekday.value); + setIsOpen(false); + }; + + return ( +
+ + + {isOpen && ( +
+ {weekdays.map((weekday) => ( + + ))} +
+ )} +
+ ); +}; + +export default FirstDayOfWeekDropdown; diff --git a/frontend/utils/profileService.ts b/frontend/utils/profileService.ts index 7a87814..bbdebe0 100644 --- a/frontend/utils/profileService.ts +++ b/frontend/utils/profileService.ts @@ -6,6 +6,7 @@ interface Profile { appearance: 'light' | 'dark'; language: string; timezone: string; + first_day_of_week: number; // 0 = Sunday, 1 = Monday, etc. avatar_image: string | null; telegram_bot_token: string | null; telegram_chat_id: string | null; @@ -241,3 +242,83 @@ export const getNextTaskSuggestionEnabled = async (): Promise => { return true; // Default to enabled if we can't fetch the setting } }; + +/** + * Gets the first day of the week (0 = Sunday, 1 = Monday, etc.) + * Falls back to locale-based defaults if not set in profile + */ +export const getFirstDayOfWeek = async (): Promise => { + try { + const profile = await fetchProfile(); + if (profile.first_day_of_week !== undefined) { + return profile.first_day_of_week; + } + + // Fallback to locale-based default + return getLocaleFirstDayOfWeek(profile.language); + } catch (error) { + console.error('Error fetching first day of week setting:', error); + // Default fallback based on browser locale + return getLocaleFirstDayOfWeek(navigator.language); + } +}; + +/** + * Returns the first day of week based on locale/language + * 0 = Sunday, 1 = Monday, etc. + */ +export const getLocaleFirstDayOfWeek = (locale: string): number => { + // Countries that typically start with Monday (1) + const mondayCountries = [ + 'de', + 'fr', + 'es', + 'it', + 'nl', + 'pt', + 'ru', + 'pl', + 'no', + 'da', + 'sv', + 'fi', + 'el', + 'tr', + 'bg', + 'ro', + 'hu', + 'cs', + 'sk', + 'hr', + 'sl', + 'et', + 'lv', + 'lt', + 'uk', + 'be', + 'at', + 'ch', + 'lu', + 'is', + 'ie', + 'gb', + 'eu', + 'zh', + 'ja', + 'ko', + ]; + + // Countries that typically start with Saturday (6) + const saturdayCountries = ['ar', 'he', 'fa']; + + // Extract language code (e.g., 'en-US' -> 'en', 'zh-CN' -> 'zh') + const langCode = locale.toLowerCase().split('-')[0]; + + if (saturdayCountries.includes(langCode)) { + return 6; // Saturday + } else if (mondayCountries.includes(langCode)) { + return 1; // Monday + } else { + return 0; // Sunday (default for US, CA, JP, etc.) + } +}; diff --git a/public/locales/bg/translation.json b/public/locales/bg/translation.json index 20673b2..93170eb 100644 --- a/public/locales/bg/translation.json +++ b/public/locales/bg/translation.json @@ -293,7 +293,8 @@ "norwegian": "Норвежки", "polish": "Полски", "slovenian": "Словенски", - "swedish": "Шведски" + "swedish": "Шведски", + "firstDayOfWeek": "Първи ден от седмицата" }, "productivity": { "stalledProjects": "Забавени проекти", @@ -901,5 +902,14 @@ "viewOnGitHub": "Вижте в GitHub", "license": "Лицензирано за лична употреба", "builtBy": "Създадено от" + }, + "weekdaysFull": { + "sunday": "Неделя", + "monday": "Понеделник", + "tuesday": "Вторник", + "wednesday": "Сряда", + "thursday": "Четвъртък", + "friday": "Петък", + "saturday": "Събота" } } diff --git a/public/locales/da/translation.json b/public/locales/da/translation.json index e923047..32ff41d 100644 --- a/public/locales/da/translation.json +++ b/public/locales/da/translation.json @@ -293,7 +293,8 @@ "aiProductivityFeatures": "AI & Produktivitetsfunktioner", "botSetup": "Bot Opsætning", "passwordChangeNote": "Ændringer af adgangskode gemmes, når du klikker på \"Gem ændringer\" nederst i formularen.", - "passwordChangeOptional": "Lad adgangskodefelterne stå tomme for at opdatere andre indstillinger uden at ændre din adgangskode." + "passwordChangeOptional": "Lad adgangskodefelterne stå tomme for at opdatere andre indstillinger uden at ændre din adgangskode.", + "firstDayOfWeek": "Første dag i ugen" }, "productivity": { "stalledProjects": "Stagnerede Projekter", @@ -901,5 +902,14 @@ "viewOnGitHub": "Se på GitHub", "license": "Licenseret til personlig brug", "builtBy": "Bygget af" + }, + "weekdaysFull": { + "sunday": "Søndag", + "monday": "Mandag", + "tuesday": "Tirsdag", + "wednesday": "Onsdag", + "thursday": "Torsdag", + "friday": "Fredag", + "saturday": "Lørdag" } } diff --git a/public/locales/de/translation.json b/public/locales/de/translation.json index 2ff3bf6..0184ee9 100644 --- a/public/locales/de/translation.json +++ b/public/locales/de/translation.json @@ -515,7 +515,8 @@ "norwegian": "Norwegisch", "polish": "Polnisch", "slovenian": "Slowenisch", - "swedish": "Schwedisch" + "swedish": "Schwedisch", + "firstDayOfWeek": "Erster Tag der Woche" }, "nextTask": { "suggestion": "Da nichts in Bearbeitung ist, wie wäre es, mit diesem zu beginnen", @@ -910,5 +911,14 @@ "viewOnGitHub": "Auf GitHub ansehen", "license": "Lizenz für die persönliche Nutzung", "builtBy": "Hergestellt von" + }, + "weekdaysFull": { + "sunday": "Sonntag", + "monday": "Montag", + "tuesday": "Dienstag", + "wednesday": "Mittwoch", + "thursday": "Donnerstag", + "friday": "Freitag", + "saturday": "Samstag" } } diff --git a/public/locales/el/translation.json b/public/locales/el/translation.json index f23e779..a273792 100644 --- a/public/locales/el/translation.json +++ b/public/locales/el/translation.json @@ -247,7 +247,8 @@ "norwegian": "Νορβηγικά", "polish": "Πολωνικά", "slovenian": "Σλοβενικά", - "swedish": "Σουηδικά" + "swedish": "Σουηδικά", + "firstDayOfWeek": "Πρώτη ημέρα της εβδομάδας" }, "errors": { "required": "Αυτό το πεδίο είναι υποχρεωτικό", @@ -905,5 +906,14 @@ "viewOnGitHub": "Δείτε στο GitHub", "license": "Αδειοδοτημένο για προσωπική χρήση", "builtBy": "Δημιουργήθηκε από" + }, + "weekdaysFull": { + "sunday": "Κυριακή", + "monday": "Δευτέρα", + "tuesday": "Τρίτη", + "wednesday": "Τετάρτη", + "thursday": "Πέμπτη", + "friday": "Παρασκευή", + "saturday": "Σάββατο" } } diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json index d1ff03a..eeacab8 100644 --- a/public/locales/en/translation.json +++ b/public/locales/en/translation.json @@ -189,6 +189,7 @@ "light": "Light", "dark": "Dark", "timezone": "Timezone", + "firstDayOfWeek": "First day of week", "saveChanges": "Save Changes", "successMessage": "Profile updated successfully!", "languageChangedNote": "Language changes are applied immediately", @@ -726,6 +727,15 @@ "parentEditWarning": "⚠️ You are editing the parent task's recurrence settings. Changes will affect all future instances of this recurring task." }, "weekdays": { + "sunday": "Sun", + "monday": "Mon", + "tuesday": "Tue", + "wednesday": "Wed", + "thursday": "Thu", + "friday": "Fri", + "saturday": "Sat" + }, + "weekdaysFull": { "sunday": "Sunday", "monday": "Monday", "tuesday": "Tuesday", diff --git a/public/locales/es/translation.json b/public/locales/es/translation.json index 4839cb4..128615c 100644 --- a/public/locales/es/translation.json +++ b/public/locales/es/translation.json @@ -247,7 +247,8 @@ "norwegian": "Noruego", "polish": "Polaco", "slovenian": "Esloveno", - "swedish": "Sueco" + "swedish": "Sueco", + "firstDayOfWeek": "Primer día de la semana" }, "errors": { "required": "Este campo es obligatorio", @@ -902,5 +903,14 @@ "viewOnGitHub": "Ver en GitHub", "license": "Licenciado para uso personal", "builtBy": "Construido por" + }, + "weekdaysFull": { + "sunday": "Domingo", + "monday": "Lunes", + "tuesday": "Martes", + "wednesday": "Miércoles", + "thursday": "Jueves", + "friday": "Viernes", + "saturday": "Sábado" } } diff --git a/public/locales/fi/translation.json b/public/locales/fi/translation.json index 7d64580..e7e65e6 100644 --- a/public/locales/fi/translation.json +++ b/public/locales/fi/translation.json @@ -293,7 +293,8 @@ "aiProductivityFeatures": "AI & Tuottavuusominaisuudet", "botSetup": "Botti-asetukset", "passwordChangeNote": "Salasanan muutokset tallennetaan, kun napsautat \"Tallenna muutokset\" lomakkeen alareunassa.", - "passwordChangeOptional": "Jätä salasanakentät tyhjiksi päivittääksesi muita asetuksia ilman salasanan vaihtamista." + "passwordChangeOptional": "Jätä salasanakentät tyhjiksi päivittääksesi muita asetuksia ilman salasanan vaihtamista.", + "firstDayOfWeek": "Viikon ensimmäinen päivä" }, "productivity": { "stalledProjects": "Jumiutuneet projektit", @@ -901,5 +902,14 @@ "viewOnGitHub": "Näytä GitHubissa", "license": "Lisensoitu henkilökohtaiseen käyttöön", "builtBy": "Rakentanut" + }, + "weekdaysFull": { + "sunday": "Sunnuntai", + "monday": "Maanantai", + "tuesday": "Tiistai", + "wednesday": "Keskiviikko", + "thursday": "Torstai", + "friday": "Perjantai", + "saturday": "Lauantai" } } diff --git a/public/locales/fr/translation.json b/public/locales/fr/translation.json index 62704be..c1a4c19 100644 --- a/public/locales/fr/translation.json +++ b/public/locales/fr/translation.json @@ -293,7 +293,8 @@ "norwegian": "Norvégien", "polish": "Polonais", "slovenian": "Slovène", - "swedish": "Suédois" + "swedish": "Suédois", + "firstDayOfWeek": "Premier jour de la semaine" }, "productivity": { "stalledProjects": "Projets Bloqués", @@ -901,5 +902,14 @@ "viewOnGitHub": "Voir sur GitHub", "license": "Licence pour usage personnel", "builtBy": "Construit par" + }, + "weekdaysFull": { + "sunday": "Dimanche", + "monday": "Lundi", + "tuesday": "Mardi", + "wednesday": "Mercredi", + "thursday": "Jeudi", + "friday": "Vendredi", + "saturday": "Samedi" } } diff --git a/public/locales/id/translation.json b/public/locales/id/translation.json index 8eb3e94..1632ab3 100644 --- a/public/locales/id/translation.json +++ b/public/locales/id/translation.json @@ -293,7 +293,8 @@ "norwegian": "Norwegia", "polish": "Polandia", "slovenian": "Slovenia", - "swedish": "Swedia" + "swedish": "Swedia", + "firstDayOfWeek": "Hari pertama dalam minggu" }, "productivity": { "stalledProjects": "Proyek Terhenti", @@ -901,5 +902,14 @@ "viewOnGitHub": "Lihat di GitHub", "license": "Lisensi untuk penggunaan pribadi", "builtBy": "Dibangun oleh" + }, + "weekdaysFull": { + "sunday": "Minggu", + "monday": "Senin", + "tuesday": "Selasa", + "wednesday": "Rabu", + "thursday": "Kamis", + "friday": "Jumat", + "saturday": "Sabtu" } } diff --git a/public/locales/it/translation.json b/public/locales/it/translation.json index 8c6a819..37840af 100644 --- a/public/locales/it/translation.json +++ b/public/locales/it/translation.json @@ -293,7 +293,8 @@ "norwegian": "Norvegese", "polish": "Polacco", "slovenian": "Sloveno", - "swedish": "Svedese" + "swedish": "Svedese", + "firstDayOfWeek": "Primo giorno della settimana" }, "productivity": { "stalledProjects": "Progetti Bloccati", @@ -901,5 +902,14 @@ "viewOnGitHub": "Visualizza su GitHub", "license": "Licenza per uso personale", "builtBy": "Creato da" + }, + "weekdaysFull": { + "sunday": "Domenica", + "monday": "Lunedì", + "tuesday": "Martedì", + "wednesday": "Mercoledì", + "thursday": "Giovedì", + "friday": "Venerdì", + "saturday": "Sabato" } } diff --git a/public/locales/jp/translation.json b/public/locales/jp/translation.json index 3236c46..e323566 100644 --- a/public/locales/jp/translation.json +++ b/public/locales/jp/translation.json @@ -293,7 +293,8 @@ "norwegian": "ノルウェー語", "polish": "ポーランド語", "slovenian": "スロベニア語", - "swedish": "スウェーデン語" + "swedish": "スウェーデン語", + "firstDayOfWeek": "週の最初の日" }, "nextTask": { "suggestion": "進行中のものがないので、こちらから始めてみませんか", @@ -901,5 +902,14 @@ "viewOnGitHub": "GitHubで見る", "license": "個人使用のためのライセンス", "builtBy": "作成者" + }, + "weekdaysFull": { + "sunday": "日曜日", + "monday": "月曜日", + "tuesday": "火曜日", + "wednesday": "水曜日", + "thursday": "木曜日", + "friday": "金曜日", + "saturday": "土曜日" } } diff --git a/public/locales/ko/translation.json b/public/locales/ko/translation.json index cbd4775..0050d25 100644 --- a/public/locales/ko/translation.json +++ b/public/locales/ko/translation.json @@ -293,7 +293,8 @@ "norwegian": "노르웨이어", "polish": "폴란드어", "slovenian": "슬로베니아어", - "swedish": "스웨덴어" + "swedish": "스웨덴어", + "firstDayOfWeek": "주간의 첫 번째 날" }, "productivity": { "stalledProjects": "정체된 프로젝트", @@ -901,5 +902,14 @@ "viewOnGitHub": "GitHub에서 보기", "license": "개인 사용을 위한 라이센스", "builtBy": "제작자" + }, + "weekdaysFull": { + "sunday": "일요일", + "monday": "월요일", + "tuesday": "화요일", + "wednesday": "수요일", + "thursday": "목요일", + "friday": "금요일", + "saturday": "토요일" } } diff --git a/public/locales/nl/translation.json b/public/locales/nl/translation.json index 2254cac..284f4ae 100644 --- a/public/locales/nl/translation.json +++ b/public/locales/nl/translation.json @@ -293,7 +293,8 @@ "norwegian": "Noors", "polish": "Pools", "slovenian": "Sloveens", - "swedish": "Zweeds" + "swedish": "Zweeds", + "firstDayOfWeek": "Eerste dag van de week" }, "productivity": { "stalledProjects": "Stagnerende Projecten", @@ -901,5 +902,14 @@ "viewOnGitHub": "Bekijk op GitHub", "license": "Gelicenseerd voor persoonlijk gebruik", "builtBy": "Gebouwd door" + }, + "weekdaysFull": { + "sunday": "Zondag", + "monday": "Maandag", + "tuesday": "Dinsdag", + "wednesday": "Woensdag", + "thursday": "Donderdag", + "friday": "Vrijdag", + "saturday": "Zaterdag" } } diff --git a/public/locales/no/translation.json b/public/locales/no/translation.json index 39acf8d..4258b01 100644 --- a/public/locales/no/translation.json +++ b/public/locales/no/translation.json @@ -293,7 +293,8 @@ "aiProductivityFeatures": "AI & Produktivitetsfunksjoner", "botSetup": "Botoppsett", "passwordChangeNote": "Endringer i passordet vil bli lagret når du klikker på \"Lagre endringer\" nederst i skjemaet.", - "passwordChangeOptional": "La passordfeltene stå tomme for å oppdatere andre innstillinger uten å endre passordet ditt." + "passwordChangeOptional": "La passordfeltene stå tomme for å oppdatere andre innstillinger uten å endre passordet ditt.", + "firstDayOfWeek": "Første dag i uken" }, "productivity": { "stalledProjects": "Stagnerte prosjekter", @@ -901,5 +902,14 @@ "viewOnGitHub": "Se på GitHub", "license": "Lisensiert for personlig bruk", "builtBy": "Bygget av" + }, + "weekdaysFull": { + "sunday": "Søndag", + "monday": "Mandag", + "tuesday": "Tirsdag", + "wednesday": "Onsdag", + "thursday": "Torsdag", + "friday": "Fredag", + "saturday": "Lørdag" } } diff --git a/public/locales/pl/translation.json b/public/locales/pl/translation.json index 75c14f1..13d8bbc 100644 --- a/public/locales/pl/translation.json +++ b/public/locales/pl/translation.json @@ -293,7 +293,8 @@ "aiProductivityFeatures": "Funkcje AI i produktywności", "botSetup": "Konfiguracja bota", "passwordChangeNote": "Zmiany hasła zostaną zapisane po kliknięciu \"Zapisz zmiany\" na dole formularza.", - "passwordChangeOptional": "Pozostaw puste pola hasła, aby zaktualizować inne ustawienia bez zmiany hasła." + "passwordChangeOptional": "Pozostaw puste pola hasła, aby zaktualizować inne ustawienia bez zmiany hasła.", + "firstDayOfWeek": "Pierwszy dzień tygodnia" }, "productivity": { "stalledProjects": "Zatrzymane projekty", @@ -901,5 +902,14 @@ "viewOnGitHub": "Zobacz na GitHubie", "license": "Licencjonowane do użytku osobistego", "builtBy": "Stworzone przez" + }, + "weekdaysFull": { + "sunday": "Niedziela", + "monday": "Poniedziałek", + "tuesday": "Wtorek", + "wednesday": "Środa", + "thursday": "Czwartek", + "friday": "Piątek", + "saturday": "Sobota" } } diff --git a/public/locales/pt/translation.json b/public/locales/pt/translation.json index 59c26c5..d27f212 100644 --- a/public/locales/pt/translation.json +++ b/public/locales/pt/translation.json @@ -293,7 +293,8 @@ "norwegian": "Norueguês", "polish": "Polonês", "slovenian": "Esloveno", - "swedish": "Sueco" + "swedish": "Sueco", + "firstDayOfWeek": "Primeiro dia da semana" }, "productivity": { "stalledProjects": "Projetos Parados", @@ -901,5 +902,14 @@ "viewOnGitHub": "Ver no GitHub", "license": "Licenciado para uso pessoal", "builtBy": "Construído por" + }, + "weekdaysFull": { + "sunday": "Domingo", + "monday": "Segunda-feira", + "tuesday": "Terça-feira", + "wednesday": "Quarta-feira", + "thursday": "Quinta-feira", + "friday": "Sexta-feira", + "saturday": "Sábado" } } diff --git a/public/locales/ro/translation.json b/public/locales/ro/translation.json index 133eb81..7f90334 100644 --- a/public/locales/ro/translation.json +++ b/public/locales/ro/translation.json @@ -293,7 +293,8 @@ "norwegian": "Norvegiană", "polish": "Poloneză", "slovenian": "Slovenă", - "swedish": "Suedeză" + "swedish": "Suedeză", + "firstDayOfWeek": "Prima zi a săptămânii" }, "productivity": { "stalledProjects": "Proiecte Blocate", @@ -901,5 +902,14 @@ "viewOnGitHub": "Vezi pe GitHub", "license": "Licențiat pentru uz personal", "builtBy": "Construit de" + }, + "weekdaysFull": { + "sunday": "Duminică", + "monday": "Luni", + "tuesday": "Marți", + "wednesday": "Miercuri", + "thursday": "Joi", + "friday": "Vineri", + "saturday": "Sâmbătă" } } diff --git a/public/locales/ru/translation.json b/public/locales/ru/translation.json index d712974..51ae21e 100644 --- a/public/locales/ru/translation.json +++ b/public/locales/ru/translation.json @@ -293,7 +293,8 @@ "norwegian": "Норвежский", "polish": "Польский", "slovenian": "Словенский", - "swedish": "Шведский" + "swedish": "Шведский", + "firstDayOfWeek": "Первый день недели" }, "productivity": { "stalledProjects": "Приостановленные проекты", @@ -901,5 +902,14 @@ "viewOnGitHub": "Посмотреть на GitHub", "license": "Лицензировано для личного использования", "builtBy": "Создано" + }, + "weekdaysFull": { + "sunday": "Воскресенье", + "monday": "Понедельник", + "tuesday": "Вторник", + "wednesday": "Среда", + "thursday": "Четверг", + "friday": "Пятница", + "saturday": "Суббота" } } diff --git a/public/locales/sl/translation.json b/public/locales/sl/translation.json index 90ce038..2fc2b21 100644 --- a/public/locales/sl/translation.json +++ b/public/locales/sl/translation.json @@ -293,7 +293,8 @@ "aiProductivityFeatures": "AI in funkcije produktivnosti", "botSetup": "Nastavitev bota", "passwordChangeNote": "Spremembe gesla bodo shranjene, ko kliknete \"Shrani spremembe\" na dnu obrazca.", - "passwordChangeOptional": "Pustite polja za geslo prazna, da posodobite druge nastavitve brez spreminjanja gesla." + "passwordChangeOptional": "Pustite polja za geslo prazna, da posodobite druge nastavitve brez spreminjanja gesla.", + "firstDayOfWeek": "Prvi dan v tednu" }, "productivity": { "stalledProjects": "Zastali projekti", @@ -901,5 +902,14 @@ "viewOnGitHub": "Poglej na GitHubu", "license": "Licencirano za osebno uporabo", "builtBy": "Zgrajeno od" + }, + "weekdaysFull": { + "sunday": "Nedelja", + "monday": "Ponedeljek", + "tuesday": "Torek", + "wednesday": "Sreda", + "thursday": "Četrtek", + "friday": "Petek", + "saturday": "Sobota" } } diff --git a/public/locales/sv/translation.json b/public/locales/sv/translation.json index d3ab712..1492cb9 100644 --- a/public/locales/sv/translation.json +++ b/public/locales/sv/translation.json @@ -293,7 +293,8 @@ "aiProductivityFeatures": "AI & Produktivitetsfunktioner", "botSetup": "Bot-inställningar", "passwordChangeNote": "Ändringar av lösenordet sparas när du klickar på \"Spara ändringar\" längst ner i formuläret.", - "passwordChangeOptional": "Lämna lösenordsfälten tomma för att uppdatera andra inställningar utan att ändra ditt lösenord." + "passwordChangeOptional": "Lämna lösenordsfälten tomma för att uppdatera andra inställningar utan att ändra ditt lösenord.", + "firstDayOfWeek": "Första dagen i veckan" }, "productivity": { "stalledProjects": "Stagnerade projekt", @@ -901,5 +902,14 @@ "viewOnGitHub": "Visa på GitHub", "license": "Licensierad för personligt bruk", "builtBy": "Utvecklat av" + }, + "weekdaysFull": { + "sunday": "Söndag", + "monday": "Måndag", + "tuesday": "Tisdag", + "wednesday": "Onsdag", + "thursday": "Torsdag", + "friday": "Fredag", + "saturday": "Lördag" } } diff --git a/public/locales/tr/translation.json b/public/locales/tr/translation.json index 3c8bc14..a234632 100644 --- a/public/locales/tr/translation.json +++ b/public/locales/tr/translation.json @@ -293,7 +293,8 @@ "norwegian": "Norveççe", "polish": "Lehçe", "slovenian": "Slovence", - "swedish": "İsveççe" + "swedish": "İsveççe", + "firstDayOfWeek": "Haftanın ilk günü" }, "productivity": { "stalledProjects": "Duraklayan Projeler", @@ -901,5 +902,14 @@ "viewOnGitHub": "GitHub'da Görüntüle", "license": "Kişisel kullanım için lisanslı", "builtBy": "Yapan" + }, + "weekdaysFull": { + "sunday": "Pazar", + "monday": "Pazartesi", + "tuesday": "Salı", + "wednesday": "Çarşamba", + "thursday": "Perşembe", + "friday": "Cuma", + "saturday": "Cumartesi" } } diff --git a/public/locales/ua/translation.json b/public/locales/ua/translation.json index 8c9963c..2c5d8e1 100644 --- a/public/locales/ua/translation.json +++ b/public/locales/ua/translation.json @@ -551,7 +551,8 @@ "norwegian": "Норвезька", "polish": "Польська", "slovenian": "Словенська", - "swedish": "Шведська" + "swedish": "Шведська", + "firstDayOfWeek": "Перший день тижня" }, "task": { "suggestions": { @@ -901,5 +902,14 @@ "viewOnGitHub": "Переглянути на GitHub", "license": "Ліцензовано для особистого використання", "builtBy": "Створено" + }, + "weekdaysFull": { + "sunday": "Неділя", + "monday": "Понеділок", + "tuesday": "Вівторок", + "wednesday": "Середа", + "thursday": "Четвер", + "friday": "П'ятниця", + "saturday": "Субота" } } diff --git a/public/locales/vi/translation.json b/public/locales/vi/translation.json index 74dc6aa..3dae65d 100644 --- a/public/locales/vi/translation.json +++ b/public/locales/vi/translation.json @@ -293,7 +293,8 @@ "norwegian": "Tiếng Na Uy", "polish": "Tiếng Ba Lan", "slovenian": "Tiếng Slovenia", - "swedish": "Thụy Điển" + "swedish": "Thụy Điển", + "firstDayOfWeek": "Ngày đầu tiên của tuần" }, "productivity": { "stalledProjects": "Dự án Đang Tạm Dừng", @@ -901,5 +902,14 @@ "viewOnGitHub": "Xem trên GitHub", "license": "Cấp phép cho sử dụng cá nhân", "builtBy": "Được xây dựng bởi" + }, + "weekdaysFull": { + "sunday": "Chủ nhật", + "monday": "Thứ hai", + "tuesday": "Thứ ba", + "wednesday": "Thứ tư", + "thursday": "Thứ năm", + "friday": "Thứ sáu", + "saturday": "Thứ bảy" } } diff --git a/public/locales/zh/translation.json b/public/locales/zh/translation.json index 2941234..21cfdbe 100644 --- a/public/locales/zh/translation.json +++ b/public/locales/zh/translation.json @@ -293,7 +293,8 @@ "norwegian": "挪威语", "polish": "波兰语", "slovenian": "斯洛文尼亚语", - "swedish": "瑞典语" + "swedish": "瑞典语", + "firstDayOfWeek": "一周的第一天" }, "productivity": { "stalledProjects": "停滞项目", @@ -901,5 +902,14 @@ "viewOnGitHub": "在GitHub上查看", "license": "个人使用许可证", "builtBy": "构建者" + }, + "weekdaysFull": { + "sunday": "星期日", + "monday": "星期一", + "tuesday": "星期二", + "wednesday": "星期三", + "thursday": "星期四", + "friday": "星期五", + "saturday": "星期六" } }