diff --git a/src/components/sections/compensation-calculator/Calculator.tsx b/src/components/sections/compensation-calculator/Calculator.tsx new file mode 100644 index 000000000..4190de525 --- /dev/null +++ b/src/components/sections/compensation-calculator/Calculator.tsx @@ -0,0 +1,140 @@ +"use client"; + +import { use, useEffect, useOptimistic, useState } from "react"; +import Text from "src/components/text/Text"; +import { formatAsCurrency } from "src/utils/i18n"; +import { LocaleDocument } from "studio/lib/interfaces/locale"; +import { getSalaryByYear } from "./actions"; +import { + IOption, + RadioButtonGroup, +} from "src/components/forms/radioButtonGroup/RadioButtonGroup"; +import InputField from "src/components/forms/inputField/InputField"; +import Button from "src/components/buttons/Button"; + +export type Degree = "bachelor" | "master"; + +type CalculatorProps = { + initialSalary: number; + localeRes: Promise; +}; + +type SalarySettings = { + year: number; + degree: Degree; +}; + +export default function Calculator({ + localeRes, + initialSalary, +}: CalculatorProps) { + const locale = use(localeRes); + const [year, setYear] = useState(2024); + const [degree, setDegree] = useState("bachelor"); + const [salary, setSalary] = useState(initialSalary); + + if (!locale) { + console.error( + "[CompensationCalculator]: Sanity data not found. Not rendering CompensationCalculator.", + ); + return null; + } + + useEffect(() => { + async function fetchSalary() { + const salaryByYear = await getSalaryByYear(year); + console.log(salaryByYear); + + setSalary(salaryByYear.ok ? salaryByYear.value : initialSalary); + } + + fetchSalary(); + }, [year, degree]); + + return ( +
+ { + const salaryByYear = await getSalaryByYear(2024); + + console.log(salaryByYear); + }} + /> + + {salary !== null ? ( +
+ Din årslønn + + {salary} + {/* {formatAsCurrency(salary, locale.locale, locale.currency)} */} + + + bonus +
+ ) : null} +
+ ); +} + +const degreeOptions: IOption[] = [ + { id: "bachelor", label: "Bachelor" }, + { id: "master", label: "Master" }, +]; + +interface SalaryCalculatorProps { + examinationYearValue: number; + minExaminationYear: number; + maxExaminationYear: number; + selectedDegree: Degree; + onDegreeChanged: (degree: Degree) => void; + onExaminationYearChanged: (examinationYear: number) => void; + action: (data: FormData) => void; +} + +function SalaryCalculator({ + examinationYearValue: yearValue, + minExaminationYear, + maxExaminationYear, + selectedDegree, + onDegreeChanged, + onExaminationYearChanged, + action, +}: SalaryCalculatorProps) { + return ( +
+ + onDegreeChanged(selectedOption.id as Degree) + } + /> +
+ onExaminationYearChanged(parseInt(value))} + required + /> +
+ + + ); +} diff --git a/src/components/sections/compensation-calculator/CompensationCalculator.tsx b/src/components/sections/compensation-calculator/CompensationCalculator.tsx index 052ae7128..7e486bcb7 100644 --- a/src/components/sections/compensation-calculator/CompensationCalculator.tsx +++ b/src/components/sections/compensation-calculator/CompensationCalculator.tsx @@ -1,10 +1,16 @@ import Text from "src/components/text/Text"; -import { SalariesByLocation } from "studio/lib/interfaces/compensations"; import { CompensationCalculatorSection } from "studio/lib/interfaces/pages"; import { COMPENSATIONS_SALARIES } from "studio/lib/queries/specialPages"; import { loadStudioQuery } from "studio/lib/store"; +import { Suspense } from "react"; +import { LocaleDocument } from "studio/lib/interfaces/locale"; +import { LOCALE_QUERY } from "studio/lib/queries/locale"; +import Calculator from "./Calculator"; +import { CompensationData } from "./types"; + import styles from "./compensation-calculator.module.css"; +import { getSalaryByYear } from "./actions"; export interface CompensationCalculatorProps { language: string; @@ -15,13 +21,18 @@ export default async function CompensationCalculator({ language, section, }: CompensationCalculatorProps) { - const employeesPageRes = await loadStudioQuery<{ - slug: string; - salariesByLocation: SalariesByLocation[]; - }>(COMPENSATIONS_SALARIES, { - language, - }); - console.log(employeesPageRes.data); + const compensationsSalariesRes = loadStudioQuery( + COMPENSATIONS_SALARIES, + { + language, + }, + ).then((d) => d.data); + + const localeRes = loadStudioQuery(LOCALE_QUERY).then( + (d) => d.data, + ); + + const data = await getSalaryByYear(2024); // TODO: add cn util or andIf const calculatorBgClassname = @@ -33,6 +44,13 @@ export default async function CompensationCalculator({ ? `${styles.handbook} ${styles["handbook--violet"]}` : styles.handbook; + if (!data.ok) { + console.error( + "[CompensationCalculator]: Failed to get salary data for year 2024", + ); + return null; + } + return (
{section.moduleTitle} @@ -41,6 +59,15 @@ export default async function CompensationCalculator({
{section.calculatorTitle} {section.calculatorDescription} + + Loading...
}> + +
{section.handbookTitle} diff --git a/src/components/sections/compensation-calculator/actions.ts b/src/components/sections/compensation-calculator/actions.ts new file mode 100644 index 000000000..4f7968c0f --- /dev/null +++ b/src/components/sections/compensation-calculator/actions.ts @@ -0,0 +1,29 @@ +"use server"; + +import { isSalariesType } from "studio/components/salariesInput/utils/parseSalaries"; +import { COMPENSATIONS_SALARY_BY_YEAR } from "studio/lib/queries/specialPages"; +import { loadStudioQuery } from "studio/lib/store"; +import { Result, ResultError, ResultOk } from "studio/utils/result"; + +export async function getSalaryByYear( + year: number, +): Promise> { + const res = await loadStudioQuery<{ + salariesByLocation: { yearlySalaries: { salaries: string } }; + }>(COMPENSATIONS_SALARY_BY_YEAR, { + year, + }); + + try { + const parsedSalaries = JSON.parse( + res.data.salariesByLocation.yearlySalaries.salaries, + ); + if (!isSalariesType(parsedSalaries) || !parsedSalaries[year]) { + return ResultError("Parsed salaries data was not valid"); + } + + return ResultOk(parsedSalaries[year] as number); + } catch (e) { + return ResultError("Parsed salaries data was not valid"); + } +} diff --git a/src/components/sections/compensation-calculator/types.ts b/src/components/sections/compensation-calculator/types.ts new file mode 100644 index 000000000..a46f59e63 --- /dev/null +++ b/src/components/sections/compensation-calculator/types.ts @@ -0,0 +1,6 @@ +import { SalariesByLocation } from "studio/lib/interfaces/compensations"; + +export type CompensationData = { + slug: string; + salariesByLocation: SalariesByLocation[]; +}; diff --git a/studio/lib/queries/specialPages.ts b/studio/lib/queries/specialPages.ts index 781a4eb90..2fc37ad38 100644 --- a/studio/lib/queries/specialPages.ts +++ b/studio/lib/queries/specialPages.ts @@ -34,6 +34,15 @@ export const COMPENSATIONS_SALARIES = groq` }, } `; +export const COMPENSATIONS_SALARY_BY_YEAR = groq` + *[_type == "compensations"][0] { + "salariesByLocation": salariesByLocation[0] { + "yearlySalaries": yearlySalaries[0] { + ... + } + }, + } +`; export const COMPENSATIONS_PAGE_SITEMAP_QUERY = groq` *[_type == "compensations"][0] { _updatedAt,