From c99f57260dc1430f7ffbf1203a507dbdadae35b4 Mon Sep 17 00:00:00 2001 From: Yangshun Tay Date: Tue, 8 Nov 2022 17:26:49 +0800 Subject: [PATCH] [offers][feat] show currency depending on country --- .../components/offers/table/OffersTable.tsx | 8 +- apps/portal/src/middleware.ts | 11 ++ apps/portal/src/pages/offers/index.tsx | 14 ++- .../utils/offers/currency/CurrencyEnum.tsx | 114 +++++++++++++++++- 4 files changed, 143 insertions(+), 4 deletions(-) create mode 100644 apps/portal/src/middleware.ts diff --git a/apps/portal/src/components/offers/table/OffersTable.tsx b/apps/portal/src/components/offers/table/OffersTable.tsx index 3b78e783..a3817d23 100644 --- a/apps/portal/src/components/offers/table/OffersTable.tsx +++ b/apps/portal/src/components/offers/table/OffersTable.tsx @@ -14,7 +14,7 @@ import { YOE_CATEGORY_PARAM, } from '~/components/offers/table/types'; -import { Currency } from '~/utils/offers/currency/CurrencyEnum'; +import { getCurrencyForCountry } from '~/utils/offers/currency/CurrencyEnum'; import CurrencySelector from '~/utils/offers/currency/CurrencySelector'; import { useSearchParamSingle } from '~/utils/offers/useSearchParam'; import { trpc } from '~/utils/trpc'; @@ -28,17 +28,21 @@ const NUMBER_OF_OFFERS_PER_PAGE = 20; export type OffersTableProps = Readonly<{ companyFilter: string; companyName?: string; + country: string | null; countryFilter: string; jobTitleFilter: string; }>; export default function OffersTable({ + country, countryFilter, companyName, companyFilter, jobTitleFilter, }: OffersTableProps) { - const [currency, setCurrency] = useState(Currency.SGD.toString()); // TODO: Detect location + const [currency, setCurrency] = useState( + getCurrencyForCountry(country).toString(), + ); const [jobType, setJobType] = useState(JobType.FULLTIME); const [pagination, setPagination] = useState({ currentPage: 0, diff --git a/apps/portal/src/middleware.ts b/apps/portal/src/middleware.ts new file mode 100644 index 00000000..eab2b69c --- /dev/null +++ b/apps/portal/src/middleware.ts @@ -0,0 +1,11 @@ +import type { NextRequest } from 'next/server'; +import { NextResponse } from 'next/server'; + +export function middleware(request: NextRequest) { + const country = request.geo?.country ?? null; + const response = NextResponse.next(); + if (country != null) { + response.cookies.set('country', country); + } + return response; +} diff --git a/apps/portal/src/pages/offers/index.tsx b/apps/portal/src/pages/offers/index.tsx index 6dc33e5d..e7f75468 100644 --- a/apps/portal/src/pages/offers/index.tsx +++ b/apps/portal/src/pages/offers/index.tsx @@ -1,3 +1,4 @@ +import type { GetServerSideProps, InferGetServerSidePropsType } from 'next'; import Head from 'next/head'; import Link from 'next/link'; import { useState } from 'react'; @@ -15,7 +16,17 @@ import JobTitlesTypeahead from '~/components/shared/JobTitlesTypeahead'; import { useSearchParamSingle } from '~/utils/offers/useSearchParam'; -export default function OffersHomePage() { +export const getServerSideProps: GetServerSideProps = async ({ req }) => { + return { + props: { + country: req.cookies.country ?? null, + }, + }; +}; + +export default function OffersHomePage({ + country, +}: InferGetServerSidePropsType) { const [countryFilter, setCountryFilter] = useState(''); const { event: gaEvent } = useGoogleAnalytics(); @@ -140,6 +151,7 @@ export default function OffersHomePage() { diff --git a/apps/portal/src/utils/offers/currency/CurrencyEnum.tsx b/apps/portal/src/utils/offers/currency/CurrencyEnum.tsx index 6babd79c..bb8899f9 100644 --- a/apps/portal/src/utils/offers/currency/CurrencyEnum.tsx +++ b/apps/portal/src/utils/offers/currency/CurrencyEnum.tsx @@ -1,4 +1,3 @@ -// eslint-disable-next-line no-shadow export enum Currency { AED = 'AED', // 'UNITED ARAB EMIRATES DIRHAM' AFN = 'AFN', // 'AFGHAN AFGHANI' @@ -172,3 +171,116 @@ export const CURRENCY_OPTIONS = Object.entries(Currency).map( value, }), ); + +export function getCurrencyForCountry( + countryCode: string | null = 'US', +): Currency { + // Source: https://github.com/srcagency/country-currencies/blob/master/data.json + switch (countryCode) { + case 'AU': + case 'CX': + case 'CC': + case 'HM': + case 'KI': + case 'NF': + case 'NR': + case 'TV': + return Currency.AUD; + case 'AD': + case 'AT': + case 'AX': + case 'BE': + case 'BL': + case 'CY': + case 'DE': + case 'EE': + case 'ES': + case 'FI': + case 'FR': + case 'GF': + case 'GP': + case 'GR': + case 'IE': + case 'IT': + case 'LT': + case 'LU': + case 'LV': + case 'MC': + case 'ME': + case 'MF': + case 'MQ': + case 'MT': + case 'NL': + case 'PM': + case 'PT': + case 'RE': + case 'SI': + case 'SK': + case 'SM': + case 'TF': + case 'VA': + case 'WS': + case 'YT': + return Currency.EUR; + case 'GS': + case 'GB': + case 'JE': + case 'IM': + return Currency.GBP; + case 'CA': + return Currency.CAD; + case 'SG': + return Currency.SGD; + case 'JP': + return Currency.JPY; + case 'BT': + case 'IN': + return Currency.INR; + case 'BV': + case 'NO': + case 'SJ': + return Currency.NOK; + case 'BR': + return Currency.BRL; + case 'CN': + return Currency.CNY; + case 'DK': + case 'FO': + case 'GL': + return Currency.DKK; + case 'TP': + case 'ID': + return Currency.IDR; + case 'KP': + return Currency.KPW; + case 'KR': + return Currency.KRW; + case 'CH': + return Currency.CHF; + case 'MY': + return Currency.MYR; + case 'MX': + return Currency.MXN; + case 'NG': + return Currency.NGN; + case 'PH': + return Currency.PHP; + case 'PL': + return Currency.PLN; + case 'RU': + return Currency.RUB; + case 'SA': + return Currency.SAR; + case 'TW': + return Currency.TWD; + case 'TH': + return Currency.THB; + case 'TR': + return Currency.TRY; + case 'VN': + return Currency.VND; + case 'US': + default: + return Currency.USD; + } +}