Give a new account a first run, and drop to three tabs

Registering used to land you on a bare form asking for a child, with no hint
what came next. A short wizard now walks through the child, whether you are
planning alone or together, and where the day balances come from: fetched from
Försäkringskassan, entered by hand, or skipped — and if skipped, the figures
carry a badge saying they are estimates until real ones arrive.

Fetching is the first option rather than a hidden one, so the scraper is on by
default and the script that used to force it on no longer needs to.

Planning and Tips lose their tabs. Authoring moved to the calendar and the
figures moved to the overview, so both pages were only a second way to reach
what is already on screen; their routes now redirect rather than dead-end. The
dead translations went with them.

Dates also follow the chosen language now instead of always formatting as
Swedish.
This commit is contained in:
2026-09-17 22:05:54 +02:00
parent 064bcc2b3a
commit a4fce16dd1
40 changed files with 1060 additions and 4986 deletions
-2
View File
@@ -16,8 +16,6 @@ export const common = {
'nav.logout': 'Log out',
'nav.logoutAria': 'Log out',
'nav.overview': 'Overview',
'nav.plan': 'Plan',
'nav.selectChildAria': 'Select child',
'nav.settings': 'Settings',
'nav.tips': 'Tips',
} as const
+2 -9
View File
@@ -2,25 +2,18 @@ export const dashboard = {
'age4Bars.expiringStat': '{expiring} days expiring',
'age4Bars.savableStat': '{left} of {cap} days can be saved',
'age4Bars.title': 'Days left at age 4, per parent',
'dashboard.addChildButton': 'Add child',
'dashboard.addChildIntro': 'You have no children registered yet. Add your first child to get started.',
'dashboard.addChildTitle': 'Add child',
'dashboard.addingChild': 'Adding...',
'dashboard.birthdayLabel': 'Birthday',
'dashboard.childNameLabel': 'Child\'s name',
'dashboard.createChildError': 'Could not create child',
'dashboard.daysLeft': 'Days left',
'dashboard.enterManually': 'Enter details manually',
'dashboard.estimatedBadge': 'Estimated',
'dashboard.estimatedBadgeCaption': 'No real balances have been fetched yet — these figures use the statutory assumption (480 days, none used). Fetch from Försäkringskassan or enter details manually for exact figures.',
'dashboard.expiringAtB4': 'Expiring at age 4 if the current plan is followed (all parents)',
'dashboard.expiringAtB4ForParent': 'Expiring at age 4 if the current plan is followed – {name}',
'dashboard.expiringAtB4ParentFallback': 'Parent {number}',
'dashboard.fetchFromFk': 'Fetch from Försäkringskassan',
'dashboard.fillAllFields': 'Fill in all fields',
'dashboard.hero.hasPlanMessage': '{atRisk} days are at risk of disappearing when {childName} turns 4 ({date}).',
'dashboard.hero.noPlanMessage': 'You have {days} days to plan. Without a plan, {atRisk} of them will disappear when {childName} turns 4.',
'dashboard.loading': 'Loading...',
'dashboard.moreDetailsSummary': 'More details',
'dashboard.namePlaceholder': 'Name',
'dashboard.overviewTitle': 'Overview',
'dashboard.planFold.noWishesHint': 'Add wishes under Planning to see a proposal here.',
'dashboard.planFold.summary': 'Plan proposal for the years ahead',
+2
View File
@@ -3,6 +3,7 @@ import { common } from './common'
import { auth } from './auth'
import { calendar } from './calendar'
import { dashboard } from './dashboard'
import { onboarding } from './onboarding'
import { settings } from './settings'
import { plan } from './plan'
import { wishEditor } from './wishEditor'
@@ -26,6 +27,7 @@ export const en = {
...auth,
...calendar,
...dashboard,
...onboarding,
...settings,
...plan,
...wishEditor,
+29
View File
@@ -0,0 +1,29 @@
export const onboarding = {
'onboarding.addChildButton': 'Add child',
'onboarding.addingChild': 'Adding...',
'onboarding.balancesLegend': 'Parental-leave days',
'onboarding.birthdayLabel': 'Birthday',
'onboarding.childNameLabel': 'Child\'s name',
'onboarding.continueButton': 'Continue',
'onboarding.createChildError': 'Could not create child',
'onboarding.familyIntro': 'This controls how the planner splits parental-leave days.',
'onboarding.familyTitle': 'Are you planning alone or together with a partner?',
'onboarding.fillAllFields': 'Fill in all fields',
'onboarding.finishError': 'Something went wrong. Please try again.',
'onboarding.manualFetchDescription': 'Enter your balances manually if you already know them.',
'onboarding.manualFetchTitle': 'Enter manually',
'onboarding.namePlaceholder': 'Name',
'onboarding.partnerAddedStatus': 'Partner added: {name}',
'onboarding.partnerIntro': 'Add your partner now, or do it later under Settings.',
'onboarding.partnerNameLabel': 'Partner\'s name',
'onboarding.savingFamilyError': 'Could not save the planning mode',
'onboarding.scrapeFetchDescription': 'Fastest and most accurate — fetches your exact balances automatically via BankID.',
'onboarding.scrapeFetchTitle': 'Fetch from Försäkringskassan',
'onboarding.skipButton': 'Skip for now',
'onboarding.skipHint': 'We\'ll use the statutory assumption (480 days, none used) until you enter your own figures.',
'onboarding.stepBalancesIntro': 'This tells us how many days are left to plan. You can always update this later.',
'onboarding.stepBalancesTitle': 'Fetch your parental-leave days',
'onboarding.stepChildIntro': 'Add your first child to start planning your parental leave.',
'onboarding.stepChildTitle': 'Welcome! Let\'s add your child',
'onboarding.stepIndicator': 'Step {step} of {total}',
} as const
+8 -74
View File
@@ -1,56 +1,18 @@
// `plan.*` (the standalone Plan tab) and most `planResults.*` keys were
// retired with the Plan/Tips tabs (leave is now authored on the calendar and
// Översikt carries the headline figures — see PLANNING_ENGINE_SPEC.md's
// superseding note). What's left here is the subset `planResults.*`
// `PlanFold.tsx` (the read-only plan-proposal fold on Översikt) and
// `frontend/src/utils/rejectionMessages.ts` still render, plus
// `planningModeSelector.*` (`PlanningModeSelector.tsx`, used by both
// Settings and Onboarding).
export const plan = {
'plan.addAtLeastOneWish': 'Add at least one wish above to suggest a plan.',
'plan.addWishError': 'Could not add wish',
'plan.calculating': 'Calculating...',
'plan.intro': 'Describe how you want to be on leave — for example 6 weeks every summer and 4 weeks every Christmas — and get a suggested plan showing exactly which days are already free, which cost a vacation day, and which cost a parental-benefit day.',
'plan.loading': 'Loading planning...',
'plan.proposeButton': 'Suggest plan',
'plan.removeWishError': 'Could not remove wish',
'plan.title': 'Planning',
'plan.updateWishError': 'Could not save wish',
'plan.wishesTitle': 'Your wishes',
'planResults.age4ProjectionsIntro': 'Here\'s what the 4th birthday looks like if this proposal is applied, including future recurring wishes. Your saved plan (under Overview) may show a different result.',
'planResults.age4ProjectionsTitle': 'At the child\'s 4th birthday, if this proposal is applied',
'planResults.applyButton': 'Use plan',
'planResults.applySavedPrefix': 'The plan has been saved!',
'planResults.applyingButton': 'Saving...',
'planResults.balancesTitle': 'Remaining balances after the plan',
'planResults.cancelButton': 'Cancel',
'planResults.collisionDateHeader': 'Date',
'planResults.collisionExistingHeader': 'Existing type',
'planResults.collisionProposedHeader': 'Proposed type',
'planResults.confirmOverwriteButton': 'Yes, replace the existing days',
'planResults.confirmOverwriteIntro': 'The following days are already planned and will be replaced:',
'planResults.confirmOverwriteTitle': 'Conflict with existing days',
'planResults.createdClause': '{count} new {dayWord} created',
'planResults.daySingular': 'day',
'planResults.dayTypeFree': 'free days (weekend/public holiday)',
'planResults.dayTypeLagsta': 'parental-benefit days (lägstanivå, minimum rate)',
'planResults.dayTypeSjukpenning': 'parental-benefit days (sjukpenningnivå, income-based)',
'planResults.dayTypeVacation': 'vacation days',
'planResults.daysPlural': 'days',
'planResults.detailTitle': 'Leave periods in detail',
'planResults.dubbeldagarLeftHeader': 'Double days left',
'planResults.expiringAtB4Header': 'Expiring',
'planResults.explanationDetailFree': '{free_days} fully free days (weekend/public holiday)',
'planResults.explanationDetailLagsta': '{lagsta_days} parental-benefit days (lägstanivå, minimum rate)',
'planResults.explanationDetailSjukpenning': '{sjukpenning_days} parental-benefit days (sjukpenningnivå, income-based)',
'planResults.explanationDetailVacationAndFp': 'you keep your salary for {vacation_days} days and save {fp_days} parental-benefit days',
'planResults.explanationDetailVacationOnly': '{vacation_days} vacation days',
'planResults.explanationShortfallSuffix': ' ({shortfall_days} days short)',
'planResults.explanationSummary': '{wish_name} {year} — {weeks_wished} weeks wished, {weeks_funded} weeks funded',
'planResults.fourthBirthdayHeader': '4th birthday',
'planResults.freeDaySingular': 'free day',
'planResults.freeDaysPlural': 'free days',
'planResults.fullyFunded': 'Fully funded',
'planResults.funded': 'funded',
'planResults.lagstaLeftHeader': 'Lägstanivå days left',
'planResults.leavesHeader': 'Leave periods',
'planResults.noWindowsInHorizon': 'No windows within the planning horizon.',
'planResults.parentHeader': 'Parent',
'planResults.parentalDaysTitle': 'Parental-benefit days',
'planResults.previewBanner': 'This is a suggestion — nothing is saved automatically. You can adjust your wishes above and suggest a new plan as many times as you like.',
'planResults.projectedLeftHeader': 'Projected left',
'planResults.rejectionCollisionsNeedReplace': '{count} day(s) already planned differently; pass replace=true to overwrite',
'planResults.rejectionConflictingDuplicate': 'Conflicting duplicate entries for {date} (child {child_id}, parent {parent_name}) in the same batch',
'planResults.rejectionDubbeldagBatchQuotaExceeded': 'This batch would result in {projected_total} double days, the max is {max_dubbeldagar}',
@@ -61,23 +23,7 @@ export const plan = {
'planResults.rejectionInsufficientVacationBalance': '{parent_name} would need {needed} more vacation day(s) in {year}, but only {remaining} remain',
'planResults.rejectionInvalidDayType': 'Day {index} ({date}): invalid day type "{day_type}"',
'planResults.rejectionOutsideEligibleWindow': '{date}: outside the child\'s eligible window ({birth_date} – {hard_expiry})',
'planResults.rejectionsClause': '. Rejected: {rejections}',
'planResults.remedyCarryVacationForward': '{spare_total} vacation days from previous years can be carried forward',
'planResults.remedyLowerPriorityWish': 'Lowering {wish_name} from {from_weeks} to {to_weeks} weeks frees up {freed_days} days',
'planResults.remedyReducePreschoolReserve': 'Reducing the preschool planning-day reserve ({reserved} reserved) frees up {reserved} days',
'planResults.remedyShiftWindowIntoFreeDays': 'Moving {wish_name} closer to a weekend frees up {shift_gain} days',
'planResults.replacedClause': ', {count} {dayWord} replaced',
'planResults.savableAfterB4Header': 'Savable',
'planResults.shortfallCouldNotBeFunded': '{days} {dayWord} could not be funded.',
'planResults.shortfallLabel': 'Shortfall:',
'planResults.sjukpenningLeftHeader': 'Sjukpenningnivå days left',
'planResults.skippedFreeClause': ', {count} {dayWord} skipped',
'planResults.skippedIdenticalClause': ', {count} {dayWord} skipped (already identical)',
'planResults.strategyDubbeldag': 'Double days — both parents home at the same time',
'planResults.strategyParentSwap': 'Parents alternate',
'planResults.strategyPrefix': 'Strategy:',
'planResults.strategySolo': 'One parent home',
'planResults.strategyUnplaced': 'Could not be placed — no free slot was found',
'planResults.surplusAdviceBodyFrontLoadEarlyYears': '{parent_name} has a large surplus ({days_involved} parental-benefit days) — take more days now while the child is still small and you are home anyway, rather than spreading them thinly until the 4th birthday.',
'planResults.surplusAdviceBodyShiftMixToFp': '{parent_name} could swap {days_involved} vacation day(s) for parental-benefit days in this plan — the parental-benefit days would otherwise be forfeited at the 4th birthday, while the vacation days would not.',
'planResults.surplusAdviceBodyUseLessVacation': '{parent_name} could take {days_involved} fewer vacation day(s) ({years_text}) without going below the statutory minimum ({min_vacation_days_per_year} days/year) — save them instead to cover parental-benefit days that would otherwise be forfeited.',
@@ -91,19 +37,7 @@ export const plan = {
'planResults.totalAvailableHeader': 'Total available',
'planResults.unknownParent': 'Unknown parent',
'planResults.usedHeader': 'Used',
'planResults.vacationAssumedBadge': 'Assumed',
'planResults.vacationAssumedPrompt': 'No value is recorded for this year — the statutory 25 days has been assumed. Confirm or edit it in Settings.',
'planResults.vacationDaysTitle': 'Vacation days',
'planResults.warningBodyDaysLostAtAge4': '{parent_name} risks losing {expiring_days} days at the child\'s 4th birthday ({fourth_birthday}) unless more days are used before then.',
'planResults.warningBodySgiRisk': '{parent_name} risks their SGI protection for the week starting {week_start} ({days_planned} day(s) planned, at least {min_days_per_week} required).',
'planResults.warningBodyVacationExpiring': '{parent_name} has {saved_days_in} saved vacation day(s) from {year} at risk of being forfeited.',
'planResults.warningDaysLostAtAge4': 'Days at risk of being lost at age 4',
'planResults.warningSgiRisk': 'Risk to SGI protection',
'planResults.warningVacationExpiring': 'Vacation days at risk of being lost',
'planResults.warningsTitle': 'Warnings',
'planResults.weekSingular': 'week',
'planResults.weeksUnit': 'weeks',
'planResults.wished': 'wished',
'planResults.yearHeader': 'Year',
'planResults.yearOverviewTitle': 'Overview by year',
'planningModeSelector.couple': 'Me and my partner',
-2
View File
@@ -23,7 +23,5 @@ export const tips = {
'tip.wrapRedDaysWithVacation.title': 'Make the most of public holidays',
'tip.wrapWeekendWithVacation.body': '{parent_name} has parental-benefit leave planned on Friday {friday} and Monday {monday}. A vacation day in between makes for a longer break.',
'tip.wrapWeekendWithVacation.title': 'Make the most of the weekend',
'tips.empty': 'No tips yet. Great job planning your parental leave!',
'tips.loading': 'Loading tips...',
'tips.title': 'Optimization Tips',
} as const
+5 -44
View File
@@ -1,57 +1,18 @@
// The `WishEditor.tsx`/`Plan.tsx` flow it was written for is gone (leave is
// now authored directly on the calendar). What's left here is the subset of
// keys `PeriodPopover.tsx` and `PresetRail.tsx` (both `components/calendar/*`,
// owned by another task) still render for the calendar's own flexible/season
// wish authoring — see those files before removing anything further.
export const wishEditor = {
'wishEditor.adjustBound': 'Adjust search range',
'wishEditor.adjustDates': 'Adjust dates',
'wishEditor.bothParents': 'Both parents',
'wishEditor.boundEndsLabel': 'to',
'wishEditor.boundStartsLabel': 'Search range from',
'wishEditor.boundTooShortError': 'The search range is shorter than the {weeks} weeks wished — choose a longer range or fewer weeks.',
'wishEditor.customFlexButton': '+ Custom search range',
'wishEditor.customFlexName': 'Custom search range',
'wishEditor.customLeaveButton': '+ Custom leave',
'wishEditor.customLeaveName': 'Custom leave',
'wishEditor.eitherParent': 'Either parent',
'wishEditor.emptyState': 'No leave wishes yet. Choose a suggestion above to get started.',
'wishEditor.endsLabel': 'Ends',
'wishEditor.firstYearLabel': 'First year',
'wishEditor.flexBadge': 'whenever it fits best',
'wishEditor.flexPresetsLabel': 'Quick picks — search within a season ("whenever it fits best"):',
'wishEditor.hideDates': 'Hide dates',
'wishEditor.lastYearLabel': 'Last year',
'wishEditor.modeFixed': 'Fixed dates',
'wishEditor.modeFlexible': 'Whenever it fits best',
'wishEditor.modeFlexibleExplainer': 'The engine picks the best week inside the search range below by itself — it looks for the period with the most röda dagar (public holidays) and klämdagar (bridge days), since that costs the fewest semesterdagar (vacation days). A recurring wish is re-picked every year (Easter moves, for example), and the suggestion always needs confirming in the Plan tab before it is saved, just like any other plan.',
'wishEditor.modeSectionLabel': 'How should this wish be placed?',
'wishEditor.month1': 'January',
'wishEditor.month10': 'October',
'wishEditor.month11': 'November',
'wishEditor.month12': 'December',
'wishEditor.month2': 'February',
'wishEditor.month3': 'March',
'wishEditor.month4': 'April',
'wishEditor.month5': 'May',
'wishEditor.month6': 'June',
'wishEditor.month7': 'July',
'wishEditor.month8': 'August',
'wishEditor.month9': 'September',
'wishEditor.nameAria': 'Name for {name}',
'wishEditor.parentLabel': 'Parent',
'wishEditor.presetHostlov': 'Autumn break (höstlov)',
'wishEditor.presetJullov': 'Christmas break',
'wishEditor.presetSommar': 'Summer',
'wishEditor.priorityLabel': 'Priority',
'wishEditor.recurEveryYear': 'Repeats every year',
'wishEditor.removeButton': 'Remove',
'wishEditor.retryButton': 'Try again',
'wishEditor.saveFailedStatus': 'Could not save — your edit is kept, try again.',
'wishEditor.savedStatus': 'Saved',
'wishEditor.seasonHost': 'Autumn',
'wishEditor.seasonJul': 'Christmas',
'wishEditor.seasonSommar': 'Summer',
'wishEditor.seasonVar': 'Spring',
'wishEditor.startsLabel': 'Starts',
'wishEditor.untilAge4': 'Until the child turns 4',
'wishEditor.weekUnit': 'week',
'wishEditor.weeksLabel': 'Weeks',
'wishEditor.weeksUnit': 'weeks',
'wishEditor.wrapsNote': 'Extends into the next year.',
} as const
-2
View File
@@ -16,8 +16,6 @@ export const common = {
'nav.logout': 'Logga ut',
'nav.logoutAria': 'Logga ut',
'nav.overview': 'Översikt',
'nav.plan': 'Planering',
'nav.selectChildAria': 'Välj barn',
'nav.settings': 'Inställningar',
'nav.tips': 'Tips',
} as const
+2 -9
View File
@@ -2,25 +2,18 @@ export const dashboard = {
'age4Bars.expiringStat': '{expiring} dagar förfaller',
'age4Bars.savableStat': '{left} av {cap} dagar kan sparas',
'age4Bars.title': 'Dagar kvar vid 4 års ålder, per förälder',
'dashboard.addChildButton': 'Lägg till barn',
'dashboard.addChildIntro': 'Du har inga barn registrerade ännu. Lägg till ditt första barn för att börja.',
'dashboard.addChildTitle': 'Lägg till barn',
'dashboard.addingChild': 'Lägger till...',
'dashboard.birthdayLabel': 'Födelsedag',
'dashboard.childNameLabel': 'Barnets namn',
'dashboard.createChildError': 'Kunde inte skapa barn',
'dashboard.daysLeft': 'Kvarvarande dagar',
'dashboard.enterManually': 'Ange uppgifter manuellt',
'dashboard.estimatedBadge': 'Uppskattat',
'dashboard.estimatedBadgeCaption': 'Inga verkliga saldon är hämtade än — siffrorna bygger på det lagstadgade antagandet (480 dagar, inget uttaget). Hämta från Försäkringskassan eller ange uppgifter manuellt för exakta siffror.',
'dashboard.expiringAtB4': 'Förfaller vid 4 år om nuvarande plan följs (alla föräldrar)',
'dashboard.expiringAtB4ForParent': 'Förfaller vid 4 år om nuvarande plan följs – {name}',
'dashboard.expiringAtB4ParentFallback': 'Förälder {number}',
'dashboard.fetchFromFk': 'Hämta från Försäkringskassan',
'dashboard.fillAllFields': 'Fyll i alla fält',
'dashboard.hero.hasPlanMessage': '{atRisk} dagar riskerar att försvinna när {childName} fyller 4 ({date}).',
'dashboard.hero.noPlanMessage': 'Du har {days} dagar att planera. Utan en plan försvinner {atRisk} av dem när {childName} fyller 4.',
'dashboard.loading': 'Laddar...',
'dashboard.moreDetailsSummary': 'Fler detaljer',
'dashboard.namePlaceholder': 'Namn',
'dashboard.overviewTitle': 'Översikt',
'dashboard.planFold.noWishesHint': 'Lägg till önskemål under Planering för att se ett förslag här.',
'dashboard.planFold.summary': 'Planförslag för de kommande åren',
+2
View File
@@ -2,6 +2,7 @@ import { common } from './common'
import { auth } from './auth'
import { calendar } from './calendar'
import { dashboard } from './dashboard'
import { onboarding } from './onboarding'
import { settings } from './settings'
import { plan } from './plan'
import { wishEditor } from './wishEditor'
@@ -23,6 +24,7 @@ export const sv = {
...auth,
...calendar,
...dashboard,
...onboarding,
...settings,
...plan,
...wishEditor,
+29
View File
@@ -0,0 +1,29 @@
export const onboarding = {
'onboarding.addChildButton': 'Lägg till barn',
'onboarding.addingChild': 'Lägger till...',
'onboarding.balancesLegend': 'Föräldradagar',
'onboarding.birthdayLabel': 'Födelsedag',
'onboarding.childNameLabel': 'Barnets namn',
'onboarding.continueButton': 'Fortsätt',
'onboarding.createChildError': 'Kunde inte skapa barn',
'onboarding.familyIntro': 'Det här styr hur planeraren fördelar föräldradagarna.',
'onboarding.familyTitle': 'Planerar du ensam eller tillsammans med en partner?',
'onboarding.fillAllFields': 'Fyll i alla fält',
'onboarding.finishError': 'Något gick fel. Försök igen.',
'onboarding.manualFetchDescription': 'Ange dina saldon manuellt om du redan vet dem.',
'onboarding.manualFetchTitle': 'Ange manuellt',
'onboarding.namePlaceholder': 'Namn',
'onboarding.partnerAddedStatus': 'Partner tillagd: {name}',
'onboarding.partnerIntro': 'Lägg till din partner nu, eller gör det senare under Inställningar.',
'onboarding.partnerNameLabel': 'Partnerns namn',
'onboarding.savingFamilyError': 'Kunde inte spara planeringsläget',
'onboarding.scrapeFetchDescription': 'Snabbast och säkrast — hämtar dina exakta saldon automatiskt via BankID.',
'onboarding.scrapeFetchTitle': 'Hämta från Försäkringskassan',
'onboarding.skipButton': 'Hoppa över för nu',
'onboarding.skipHint': 'Vi använder det lagstadgade antagandet (480 dagar, inget uttaget) tills du fyller i dina egna uppgifter.',
'onboarding.stepBalancesIntro': 'Så vet vi hur många dagar som finns kvar att planera. Du kan alltid uppdatera detta senare.',
'onboarding.stepBalancesTitle': 'Hämta dina föräldradagar',
'onboarding.stepChildIntro': 'Lägg till ditt första barn för att börja planera föräldraledigheten.',
'onboarding.stepChildTitle': 'Välkommen! Låt oss lägga till ditt barn',
'onboarding.stepIndicator': 'Steg {step} av {total}',
} as const
+9 -75
View File
@@ -1,56 +1,18 @@
// `plan.*` (the standalone Plan tab) and most `planResults.*` keys were
// retired with the Plan/Tips tabs (leave is now authored on the calendar and
// Översikt carries the headline figures — see PLANNING_ENGINE_SPEC.md's
// superseding note). What's left here is the subset `planResults.*`
// `PlanFold.tsx` (the read-only plan-proposal fold on Översikt) and
// `frontend/src/utils/rejectionMessages.ts` still render, plus
// `planningModeSelector.*` (`PlanningModeSelector.tsx`, used by both
// Settings and Onboarding).
export const plan = {
'plan.addAtLeastOneWish': 'Lägg till minst ett önskemål ovan för att föreslå en plan.',
'plan.addWishError': 'Kunde inte lägga till önskemål',
'plan.calculating': 'Beräknar...',
'plan.intro': 'Beskriv hur du vill vara ledig — till exempel 6 veckor varje sommar och 4 veckor varje jul — och föreslå en plan som visar exakt vilka dagar som redan är lediga, vilka som kostar en semesterdag och vilka som kostar en föräldrapenningdag.',
'plan.loading': 'Laddar planering...',
'plan.proposeButton': 'Föreslå plan',
'plan.removeWishError': 'Kunde inte ta bort önskemål',
'plan.title': 'Planering',
'plan.updateWishError': 'Kunde inte spara önskemål',
'plan.wishesTitle': 'Dina önskemål',
'planResults.age4ProjectionsIntro': 'Så här ser det ut vid 4-årsdagen om just detta förslag tillämpas, inklusive kommande års återkommande önskemål. Din sparade plan (under Översikt) kan visa ett annat resultat.',
'planResults.age4ProjectionsTitle': 'Vid barnets 4-årsdag, om detta förslag tillämpas',
'planResults.applyButton': 'Använd plan',
'planResults.applySavedPrefix': 'Planen har sparats!',
'planResults.applyingButton': 'Sparar...',
'planResults.balancesTitle': 'Kvarvarande saldon efter planen',
'planResults.cancelButton': 'Avbryt',
'planResults.collisionDateHeader': 'Datum',
'planResults.collisionExistingHeader': 'Befintlig typ',
'planResults.collisionProposedHeader': 'Föreslagen typ',
'planResults.confirmOverwriteButton': 'Ja, ersätt de befintliga dagarna',
'planResults.confirmOverwriteIntro': 'Följande dagar är redan planerade och kommer att ersättas:',
'planResults.confirmOverwriteTitle': 'Konflikt med befintliga dagar',
'planResults.createdClause': '{count} nya {dayWord} skapades',
'planResults.daySingular': 'dag',
'planResults.dayTypeFree': 'fria dagar (helg/röd dag)',
'planResults.dayTypeLagsta': 'FP-dagar (lägstanivå)',
'planResults.dayTypeSjukpenning': 'FP-dagar (sjukpenningnivå)',
'planResults.dayTypeVacation': 'semesterdagar',
'planResults.daysPlural': 'dagar',
'planResults.detailTitle': 'Ledigheter i detalj',
'planResults.dubbeldagarLeftHeader': 'Dubbeldagar kvar',
'planResults.expiringAtB4Header': 'Förfaller',
'planResults.explanationDetailFree': '{free_days} helt fria dagar (helg/röd dag)',
'planResults.explanationDetailLagsta': '{lagsta_days} föräldrapenningdagar (lägstanivå)',
'planResults.explanationDetailSjukpenning': '{sjukpenning_days} föräldrapenningdagar (sjukpenningnivå)',
'planResults.explanationDetailVacationAndFp': 'du behåller lönen {vacation_days} dagar och sparar {fp_days} FP-dagar',
'planResults.explanationDetailVacationOnly': '{vacation_days} semesterdagar',
'planResults.explanationShortfallSuffix': ' ({shortfall_days} dagar saknas)',
'planResults.explanationSummary': '{wish_name} {year} — {weeks_wished} veckor önskade, {weeks_funded} veckor finansierade',
'planResults.fourthBirthdayHeader': '4-årsdag',
'planResults.freeDaySingular': 'fri dag',
'planResults.freeDaysPlural': 'fria dagar',
'planResults.fullyFunded': 'Fullt finansierad',
'planResults.funded': 'finansierade',
'planResults.lagstaLeftHeader': 'Lägstanivådagar kvar',
'planResults.leavesHeader': 'Ledigheter',
'planResults.noWindowsInHorizon': 'Inga fönster inom planeringshorisonten.',
'planResults.parentHeader': 'Förälder',
'planResults.parentalDaysTitle': 'Föräldrapenningdagar',
'planResults.previewBanner': 'Detta är ett förslag — inget sparas automatiskt. Du kan justera dina önskemål ovan och föreslå en ny plan så många gånger du vill.',
'planResults.projectedLeftHeader': 'Beräknat kvar',
'planResults.rejectionCollisionsNeedReplace': '{count} dag(ar) är redan planerade på annat sätt; skicka replace=true för att skriva över',
'planResults.rejectionConflictingDuplicate': 'Motstridiga dubbletter för {date} (barn {child_id}, förälder {parent_name}) i samma omgång',
'planResults.rejectionDubbeldagBatchQuotaExceeded': 'Omgången skulle resultera i {projected_total} dubbeldagar, max är {max_dubbeldagar}',
@@ -61,23 +23,7 @@ export const plan = {
'planResults.rejectionInsufficientVacationBalance': '{parent_name} skulle behöva {needed} fler semesterdag(ar) {year}, men endast {remaining} finns kvar',
'planResults.rejectionInvalidDayType': 'Dag {index} ({date}): ogiltig dagtyp "{day_type}"',
'planResults.rejectionOutsideEligibleWindow': '{date}: utanför barnets tillåtna period ({birth_date} – {hard_expiry})',
'planResults.rejectionsClause': '. Avslag: {rejections}',
'planResults.remedyCarryVacationForward': '{spare_total} semesterdagar från tidigare år kan sparas framåt',
'planResults.remedyLowerPriorityWish': 'Sänk {wish_name} från {from_weeks} till {to_weeks} veckor frigör {freed_days} dagar',
'planResults.remedyReducePreschoolReserve': 'Minska förskolans planeringsdagar ({reserved} reserverade) frigör {reserved} dagar',
'planResults.remedyShiftWindowIntoFreeDays': 'Flytta {wish_name} närmare en helg frigör {shift_gain} dagar',
'planResults.replacedClause': ', {count} {dayWord} ersattes',
'planResults.savableAfterB4Header': 'Kan sparas',
'planResults.shortfallCouldNotBeFunded': '{days} {dayWord} kunde inte finansieras.',
'planResults.shortfallLabel': 'Underskott:',
'planResults.sjukpenningLeftHeader': 'Sjukpenningdagar kvar',
'planResults.skippedFreeClause': ', {count} {dayWord} hoppades över',
'planResults.skippedIdenticalClause': ', {count} {dayWord} hoppades över (redan likadana)',
'planResults.strategyDubbeldag': 'Dubbeldagar — båda föräldrarna hemma samtidigt',
'planResults.strategyParentSwap': 'Föräldrarna växlar av varandra',
'planResults.strategyPrefix': 'Strategi:',
'planResults.strategySolo': 'En förälder hemma',
'planResults.strategyUnplaced': 'Kunde inte placeras — ingen ledig plats hittades',
'planResults.surplusAdviceBodyFrontLoadEarlyYears': '{parent_name} har ett stort överskott ({days_involved} FP-dagar) — ta ut fler dagar nu medan barnet är litet och ni ändå är hemma, istället för att sprida ut dem tunt fram till 4-årsdagen.',
'planResults.surplusAdviceBodyShiftMixToFp': '{parent_name} kan byta {days_involved} semesterdagar mot föräldrapenningdagar under planen — FP-dagarna går annars förlorade vid 4-årsdagen, medan semestern inte gör det.',
'planResults.surplusAdviceBodyUseLessVacation': '{parent_name} kan ta ut {days_involved} färre semesterdagar ({years_text}) utan att gå under lägsta uttaget ({min_vacation_days_per_year} dagar/år) — spara dem istället för att täcka FP-dagar som annars går förlorade.',
@@ -91,22 +37,10 @@ export const plan = {
'planResults.totalAvailableHeader': 'Totalt tillgängliga',
'planResults.unknownParent': 'Okänd förälder',
'planResults.usedHeader': 'Använda',
'planResults.vacationAssumedBadge': 'Antaget',
'planResults.vacationAssumedPrompt': 'Inget värde är registrerat för detta år — 25 dagar (lagstadgat) har antagits. Bekräfta eller ändra i Inställningar.',
'planResults.vacationDaysTitle': 'Semesterdagar',
'planResults.warningBodyDaysLostAtAge4': '{parent_name} riskerar att förlora {expiring_days} dagar vid barnets 4-årsdag ({fourth_birthday}) om inte fler dagar tas ut innan dess.',
'planResults.warningBodySgiRisk': '{parent_name} riskerar SGI-skyddet veckan som börjar {week_start} ({days_planned} dagar planerade, minst {min_days_per_week} krävs).',
'planResults.warningBodyVacationExpiring': '{parent_name} har {saved_days_in} sparade semesterdagar från {year} som riskerar att gå förlorade.',
'planResults.warningDaysLostAtAge4': 'Dagar som riskerar att gå förlorade vid 4 år',
'planResults.warningSgiRisk': 'Risk för SGI-skydd',
'planResults.warningVacationExpiring': 'Semesterdagar som riskerar att gå förlorade',
'planResults.warningsTitle': 'Varningar',
'planResults.weekSingular': 'vecka',
'planResults.weeksUnit': 'veckor',
'planResults.wished': 'önskade',
'planResults.yearHeader': 'År',
'planResults.yearOverviewTitle': 'Översikt över åren',
'planningModeSelector.couple': 'Jag och min partner',
'planningModeSelector.legend': 'Planerar du själv eller tillsammans med en partner?',
'planningModeSelector.solo': 'Bara jag',
} as const
} as const
-2
View File
@@ -23,7 +23,5 @@ export const tips = {
'tip.wrapRedDaysWithVacation.title': 'Utnyttja röda dagar',
'tip.wrapWeekendWithVacation.body': '{parent_name} har föräldrapenning planerad fredagen {friday} och måndagen {monday}. En semesterdag mellan dem ger en längre ledighet.',
'tip.wrapWeekendWithVacation.title': 'Utnyttja helgen',
'tips.empty': 'Inga tips än. Bra jobbat med planeringen av din föräldraledighet!',
'tips.loading': 'Laddar tips...',
'tips.title': 'Optimeringstips',
} as const
+6 -45
View File
@@ -1,57 +1,18 @@
// The `WishEditor.tsx`/`Plan.tsx` flow it was written for is gone (leave is
// now authored directly on the calendar). What's left here is the subset of
// keys `PeriodPopover.tsx` and `PresetRail.tsx` (both `components/calendar/*`,
// owned by another task) still render for the calendar's own flexible/season
// wish authoring — see those files before removing anything further.
export const wishEditor = {
'wishEditor.adjustBound': 'Justera sökintervall',
'wishEditor.adjustDates': 'Justera datum',
'wishEditor.bothParents': 'Båda föräldrarna',
'wishEditor.boundEndsLabel': 'till',
'wishEditor.boundStartsLabel': 'Sökintervall från',
'wishEditor.boundTooShortError': 'Sökintervallet är kortare än de {weeks} veckor som önskas — välj ett längre intervall eller minska antalet veckor.',
'wishEditor.customFlexButton': '+ Eget sökintervall',
'wishEditor.customFlexName': 'Eget sökintervall',
'wishEditor.customLeaveButton': '+ Egen ledighet',
'wishEditor.customLeaveName': 'Egen ledighet',
'wishEditor.eitherParent': 'Endera förälder',
'wishEditor.emptyState': 'Inga ledighetsönskemål ännu. Välj ett förslag ovan för att komma igång.',
'wishEditor.endsLabel': 'Slutar',
'wishEditor.firstYearLabel': 'Första året',
'wishEditor.flexBadge': 'när det passar bäst',
'wishEditor.flexPresetsLabel': 'Snabbval — sök inom en säsong ("när det passar bäst"):',
'wishEditor.hideDates': 'Dölj datum',
'wishEditor.lastYearLabel': 'Sista året',
'wishEditor.modeFixed': 'Bestämda datum',
'wishEditor.modeFlexible': 'När det passar bäst',
'wishEditor.modeFlexibleExplainer': 'Motorn väljer själv den bästa veckan inom sökintervallet nedan — den letar efter perioden med flest röda dagar och klämdagar, eftersom det kostar minst antal semesterdagar. Vid ett återkommande önskemål väljs ett nytt fönster varje år (påsken flyttar sig till exempel), och förslaget måste alltid bekräftas i planeringsfliken innan det sparas, precis som alla andra planer.',
'wishEditor.modeSectionLabel': 'Hur ska önskemålet placeras?',
'wishEditor.month1': 'Januari',
'wishEditor.month10': 'Oktober',
'wishEditor.month11': 'November',
'wishEditor.month12': 'December',
'wishEditor.month2': 'Februari',
'wishEditor.month3': 'Mars',
'wishEditor.month4': 'April',
'wishEditor.month5': 'Maj',
'wishEditor.month6': 'Juni',
'wishEditor.month7': 'Juli',
'wishEditor.month8': 'Augusti',
'wishEditor.month9': 'September',
'wishEditor.nameAria': 'Namn för {name}',
'wishEditor.parentLabel': 'Förälder',
'wishEditor.presetHostlov': 'Höstlov',
'wishEditor.presetJullov': 'Jullov',
'wishEditor.presetSommar': 'Sommar',
'wishEditor.priorityLabel': 'Prioritet',
'wishEditor.recurEveryYear': 'Återkommer varje år',
'wishEditor.removeButton': 'Ta bort',
'wishEditor.retryButton': 'Försök igen',
'wishEditor.saveFailedStatus': 'Kunde inte spara — ändringen finns kvar, försök igen.',
'wishEditor.savedStatus': 'Sparat',
'wishEditor.seasonHost': 'Höst',
'wishEditor.seasonJul': 'Jul',
'wishEditor.seasonSommar': 'Sommar',
'wishEditor.seasonVar': 'Vår',
'wishEditor.startsLabel': 'Startar',
'wishEditor.untilAge4': 'Tills barnet fyller 4 år',
'wishEditor.weekUnit': 'vecka',
'wishEditor.weeksLabel': 'Veckor',
'wishEditor.weeksUnit': 'veckor',
'wishEditor.wrapsNote': 'Sträcker sig in i nästa år.',
} as const
} as const