diff --git a/src/app/(main)/[slug]/page.tsx b/src/app/(main)/[slug]/page.tsx index dfe51b3cf..e52b7201e 100644 --- a/src/app/(main)/[slug]/page.tsx +++ b/src/app/(main)/[slug]/page.tsx @@ -20,6 +20,8 @@ import { homeLink } from "../../../blog/components/utils/linkTypes"; import CustomErrorMessage from "../../../blog/components/customErrorMessage/CustomErrorMessage"; import { CompanyLocation } from "studio/lib/payloads/companyDetails"; import { COMPANY_LOCATIONS_QUERY } from "studio/lib/queries/companyDetails"; +import { LocaleDocument } from "../../../../studio/lib/payloads/locale"; +import { LOCALE_QUERY } from "../../../../studio/lib/queries/locale"; export const dynamic = "force-dynamic"; @@ -52,6 +54,7 @@ async function Page({ params }: Props) { initialBlogPage, initialCompensationsPage, initialLocationsData, + initialLocale, ] = await Promise.all([ loadQuery(SLUG_QUERY, { slug }, { perspective }), loadQuery(BLOG_PAGE_QUERY, { slug }, { perspective }), @@ -61,6 +64,7 @@ async function Page({ params }: Props) { { perspective }, ), loadQuery(COMPANY_LOCATIONS_QUERY, {}, { perspective }), + loadQuery(LOCALE_QUERY, {}, { perspective }), ]); if (initialPage.data) { @@ -111,11 +115,13 @@ async function Page({ params }: Props) { ) : ( ); } diff --git a/src/compensations/Compensations.tsx b/src/compensations/Compensations.tsx index a2256c751..a2204665d 100644 --- a/src/compensations/Compensations.tsx +++ b/src/compensations/Compensations.tsx @@ -13,17 +13,23 @@ import { minSalariesExaminationYear, salariesFromLocation, } from "./utils/salary"; -import { CompanyLocation } from "studio/lib/payloads/companyDetails"; +import { + CompanyInfo, + CompanyLocation, +} from "studio/lib/payloads/companyDetails"; import { IOption, RadioButtonGroup, } from "src/components/forms/radioButtonGroup/RadioButtonGroup"; import YearlyBonuses from "./components/yearlyBonuses/YearlyBonuses"; import BenefitsByLocation from "./components/benefitsByLocation/BenefitsByLocation"; +import { formatAsCurrency } from "src/utils/i18n"; +import { LocaleDocument } from "../../studio/lib/payloads/locale"; interface CompensationsProps { compensations: CompensationsPage; locations: CompanyLocation[]; + locale: LocaleDocument; } interface SalaryCalculatorFormState { @@ -31,7 +37,11 @@ interface SalaryCalculatorFormState { selectedDegree: Degree; } -const Compensations = ({ compensations, locations }: CompensationsProps) => { +const Compensations = ({ + compensations, + locations, + locale, +}: CompensationsProps) => { const [selectedLocation, setSelectedLocation] = useState( locations[0]._id, ); @@ -119,11 +129,19 @@ const Compensations = ({ compensations, locations }: CompensationsProps) => { /> {salary !== null ? (
- Du vil få en årlig lønn på {salary} + + {" "} + Du vil få en årlig lønn på{" "} + {formatAsCurrency(salary, locale.locale, locale.currency)} + {compensations.pensionPercent && ( Du vil få en årlig pensjon på omtrent{" "} - {calculatePension(salary, compensations.pensionPercent)} + {formatAsCurrency( + calculatePension(salary, compensations.pensionPercent), + locale.locale, + locale.currency, + )} )}
@@ -131,7 +149,7 @@ const Compensations = ({ compensations, locations }: CompensationsProps) => { )} {yearlyBonusesForLocation && ( - + )} diff --git a/src/compensations/CompensationsPreview.tsx b/src/compensations/CompensationsPreview.tsx index 5a592e6d3..43cfd57c2 100644 --- a/src/compensations/CompensationsPreview.tsx +++ b/src/compensations/CompensationsPreview.tsx @@ -6,15 +6,19 @@ import { CompensationsPage } from "studio/lib/payloads/compensations"; import { CompanyLocation } from "studio/lib/payloads/companyDetails"; import { COMPANY_LOCATIONS_QUERY } from "studio/lib/queries/companyDetails"; import { COMPENSATIONS_PAGE_QUERY } from "studio/lib/queries/pages"; +import { LocaleDocument } from "../../studio/lib/payloads/locale"; +import { LOCALE_QUERY } from "../../studio/lib/queries/locale"; interface CompensationsPreviewProps { initialCompensations: QueryResponseInitial; initialLocations: QueryResponseInitial; + initialLocale: QueryResponseInitial; } const CompensationsPreview = ({ initialCompensations, initialLocations, + initialLocale, }: CompensationsPreviewProps) => { const { data } = useQuery( COMPENSATIONS_PAGE_QUERY, @@ -27,10 +31,19 @@ const CompensationsPreview = ({ { initial: initialLocations }, ); + const { data: locale } = useQuery(LOCALE_QUERY, { + initial: initialLocale, + }); + return ( - locationData && ( + locationData && + locale && ( - + ) ); diff --git a/src/compensations/components/yearlyBonuses/YearlyBonuses.tsx b/src/compensations/components/yearlyBonuses/YearlyBonuses.tsx index 78c65167f..342e75c2d 100644 --- a/src/compensations/components/yearlyBonuses/YearlyBonuses.tsx +++ b/src/compensations/components/yearlyBonuses/YearlyBonuses.tsx @@ -1,12 +1,15 @@ import { BonusPage } from "studio/lib/payloads/compensations"; import Text from "../../../components/text/Text"; import styles from "./yearlyBonuses.module.css"; +import { formatAsCurrency } from "../../../utils/i18n"; +import { LocaleDocument } from "../../../../studio/lib/payloads/locale"; interface YearlyBonusesProps { bonuses: BonusPage[]; + locale: LocaleDocument; } -const YearlyBonuses = ({ bonuses }: YearlyBonusesProps) => { +const YearlyBonuses = ({ bonuses, locale }: YearlyBonusesProps) => { return (
Historisk bonus @@ -30,7 +33,13 @@ const YearlyBonuses = ({ bonuses }: YearlyBonusesProps) => { {bonus.year} - {bonus.bonus} + + {formatAsCurrency( + bonus.bonus, + locale.locale, + locale.currency, + )} + ))} diff --git a/src/utils/i18n.ts b/src/utils/i18n.ts new file mode 100644 index 000000000..68a2d62e4 --- /dev/null +++ b/src/utils/i18n.ts @@ -0,0 +1,9 @@ +export function formatAsCurrency( + number: number, + locale: string, + currency: string, +) { + return new Intl.NumberFormat(locale, { style: "currency", currency }).format( + number, + ); +} diff --git a/studio/lib/payloads/locale.ts b/studio/lib/payloads/locale.ts new file mode 100644 index 000000000..1a66c8902 --- /dev/null +++ b/studio/lib/payloads/locale.ts @@ -0,0 +1,4 @@ +export interface LocaleDocument { + locale: string; + currency: string; +} diff --git a/studio/lib/queries/locale.ts b/studio/lib/queries/locale.ts new file mode 100644 index 000000000..4f36742a8 --- /dev/null +++ b/studio/lib/queries/locale.ts @@ -0,0 +1,4 @@ +import { groq } from "next-sanity"; +import { localeID } from "../../schemas/documents/locale"; + +export const LOCALE_QUERY = groq`*[_type == "${localeID}" && _id == "${localeID}"][0]`; diff --git a/studio/schema.ts b/studio/schema.ts index f3b706796..3649cd21a 100644 --- a/studio/schema.ts +++ b/studio/schema.ts @@ -18,6 +18,7 @@ import benefitsByLocation from "./schemas/objects/compensations/benefitsByLocati import supportedLanguages from "./schemas/documents/supportedLanguages"; import defaultSeo from "./schemas/documents/admin/defaultSeo"; import brandAssets from "./schemas/documents/brandAssets"; +import locale from "./schemas/documents/locale"; export const schema: { types: SchemaTypeDefinition[] } = { types: [ @@ -40,5 +41,6 @@ export const schema: { types: SchemaTypeDefinition[] } = { supportedLanguages, defaultSeo, brandAssets, + locale, ], }; diff --git a/studio/schemas/deskStructure.ts b/studio/schemas/deskStructure.ts index 43f524fb4..253ff2728 100644 --- a/studio/schemas/deskStructure.ts +++ b/studio/schemas/deskStructure.ts @@ -25,6 +25,7 @@ import { companyLocationID } from "./documents/companyLocation"; import { supportedLanguagesID } from "./documents/supportedLanguages"; import { defaultSeoID } from "./documents/admin/defaultSeo"; import { brandAssetsID } from "./documents/brandAssets"; +import { localeID } from "./documents/locale"; // Admin Section const adminSection = (S: StructureBuilder) => @@ -101,6 +102,15 @@ const siteSettingSection = (S: StructureBuilder) => .documentId(supportedLanguagesID) .title("Supported Languages"), ), + S.listItem() + .title("Locale") + .icon(TranslateIcon) + .child( + S.document() + .schemaType(localeID) + .documentId(localeID) + .title("Locale"), + ), S.listItem() .title("Default SEO") .icon(SearchIcon) diff --git a/studio/schemas/documents/locale.ts b/studio/schemas/documents/locale.ts new file mode 100644 index 000000000..e71e675c8 --- /dev/null +++ b/studio/schemas/documents/locale.ts @@ -0,0 +1,40 @@ +import { defineField, defineType } from "sanity"; +import { relevantCurrencies } from "../../utils/currencies"; +import { relevantLocales } from "../../utils/locales"; + +export const localeID = "locale"; + +const locale = defineType({ + name: localeID, + type: "document", + fields: [ + defineField({ + name: "locale", + type: "string", + title: "Locale", + description: "Select the most relevant locale for the website.", + initialValue: relevantLocales[0].code, + options: { + list: relevantLocales.map(({ title, code }) => ({ + title: `${title} (${code})`, + value: code, + })), + }, + }), + defineField({ + name: "currency", + type: "string", + title: "Currency", + description: "Select the most relevant currency for the website.", + initialValue: relevantCurrencies[0], + options: { + list: relevantCurrencies.map((currency) => ({ + title: currency, + value: currency, + })), + }, + }), + ], +}); + +export default locale; diff --git a/studio/utils/currencies.ts b/studio/utils/currencies.ts new file mode 100644 index 000000000..9d8bb4aaf --- /dev/null +++ b/studio/utils/currencies.ts @@ -0,0 +1,10 @@ +// ISO 4217 currency codes (https://en.wikipedia.org/wiki/ISO_4217#List_of_ISO_4217_currency_codes) +export const relevantCurrencies = [ + "NOK", + "SEK", + "EUR", + "GBP", + "USD", + "DKK", + "ISK", +]; diff --git a/studio/utils/locales.ts b/studio/utils/locales.ts new file mode 100644 index 000000000..c95e7c34b --- /dev/null +++ b/studio/utils/locales.ts @@ -0,0 +1,39 @@ +interface Locale { + title: string; + code: string; +} + +export const relevantLocales: Locale[] = [ + { + title: "Norway", + code: "nb-NO", + }, + { + title: "Norway", + code: "nn-NO", + }, + { + title: "Sweden", + code: "sv-SE", + }, + { + title: "United Kingdom", + code: "en-GB", + }, + { + title: "United States", + code: "en-US", + }, + { + title: "Denmark", + code: "da-DK", + }, + { + title: "Finland", + code: "fi-FI", + }, + { + title: "Iceland", + code: "is-IS", + }, +];