diff --git a/app/(marketing)/pricing/page.tsx b/app/(marketing)/pricing/page.tsx deleted file mode 100644 index fdeaba4..0000000 --- a/app/(marketing)/pricing/page.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import { PricingTable } from '@kit/billing-gateway/marketing'; - -import { SitePageHeader } from '~/(marketing)/_components/site-page-header'; -import billingConfig from '~/config/billing.config'; -import pathsConfig from '~/config/paths.config'; -import { createI18nServerInstance } from '~/lib/i18n/i18n.server'; -import { withI18n } from '~/lib/i18n/with-i18n'; - -export const generateMetadata = async () => { - const { t } = await createI18nServerInstance(); - - return { - title: t('marketing:pricing'), - }; -}; - -const paths = { - signUp: pathsConfig.auth.signUp, - return: pathsConfig.app.home, -}; - -async function PricingPage() { - const { t } = await createI18nServerInstance(); - - return ( -
- - -
- -
-
- ); -} - -export default withI18n(PricingPage); diff --git a/app/home/(user)/_components/compare-packages-modal.tsx b/app/home/(user)/_components/compare-packages-modal.tsx new file mode 100644 index 0000000..d830b45 --- /dev/null +++ b/app/home/(user)/_components/compare-packages-modal.tsx @@ -0,0 +1,204 @@ +import { JSX } from 'react'; + +import { QuestionMarkCircledIcon } from '@radix-ui/react-icons'; +import { VisuallyHidden } from '@radix-ui/react-visually-hidden'; +import { Check, X } from 'lucide-react'; + +import { + Dialog, + DialogContent, + DialogTitle, + DialogTrigger, +} from '@kit/ui/dialog'; +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from '@kit/ui/table'; + +import { createI18nServerInstance } from '~/lib/i18n/i18n.server'; +import { withI18n } from '~/lib/i18n/with-i18n'; + +import { PackageHeader } from '../../../../components/package-header'; +import { InfoTooltip } from '../../../../components/ui/info-tooltip'; + +const dummyCards = [ + { + titleKey: 'product:standard.label', + price: 40, + nrOfAnalyses: 4, + tagColor: 'bg-cyan', + }, + { + titleKey: 'product:standardPlus.label', + price: 85, + nrOfAnalyses: 10, + tagColor: 'bg-warning', + }, + { + titleKey: 'product:premium.label', + price: 140, + nrOfAnalyses: '12+', + tagColor: 'bg-purple', + }, +]; + +const dummyRows = [ + { + analysisNameKey: 'product:clinicalBloodDraw.label', + tooltipContentKey: 'product:clinicalBloodDraw.description', + includedInStandard: 1, + includedInStandardPlus: 1, + includedInPremium: 1, + }, + { + analysisNameKey: 'product:crp.label', + tooltipContentKey: 'product:crp.description', + includedInStandard: 1, + includedInStandardPlus: 1, + includedInPremium: 1, + }, + { + analysisNameKey: 'product:ferritin.label', + tooltipContentKey: 'product:ferritin.description', + includedInStandard: 0, + includedInStandardPlus: 1, + includedInPremium: 1, + }, + { + analysisNameKey: 'product:vitaminD.label', + tooltipContentKey: 'product:vitaminD.description', + includedInStandard: 0, + includedInStandardPlus: 1, + includedInPremium: 1, + }, + { + analysisNameKey: 'product:glucose.label', + tooltipContentKey: 'product:glucose.description', + includedInStandard: 1, + includedInStandardPlus: 1, + includedInPremium: 1, + }, + { + analysisNameKey: 'product:alat.label', + tooltipContentKey: 'product:alat.description', + includedInStandard: 1, + includedInStandardPlus: 1, + includedInPremium: 1, + }, + { + analysisNameKey: 'product:ast.label', + tooltipContentKey: 'product:ast.description', + includedInStandard: 1, + includedInStandardPlus: 1, + includedInPremium: 1, + }, +]; + +const CheckWithBackground = () => { + return ( +
+ +
+ ); +}; + +const ComparePackagesModal = async ({ + triggerElement, +}: { + triggerElement: JSX.Element; +}) => { + const { t, language } = await createI18nServerInstance(); + + return ( + + {triggerElement} + +

+ {t('common:close')} +

+ + + } + preventAutoFocus + > + + {t('common:comparePackages')} + +
+
+

{t('product:healthPackageComparison.label')}

+

+ {t('product:healthPackageComparison.description')} +

+
+ + + + + {dummyCards.map( + ({ titleKey, price, nrOfAnalyses, tagColor }) => ( + + + + ), + )} + + + + {dummyRows.map( + ( + { + analysisNameKey, + tooltipContentKey, + includedInStandard, + includedInStandardPlus, + includedInPremium, + }, + index, + ) => ( + + + {t(analysisNameKey)}{' '} + } + /> + + + {!!includedInStandard && } + + + {!!includedInStandardPlus && } + + + {!!includedInPremium && } + + + ), + )} + +
+
+
+
+
+
+ ); +}; + +export default withI18n(ComparePackagesModal); diff --git a/app/home/(user)/_components/home-menu-navigation.tsx b/app/home/(user)/_components/home-menu-navigation.tsx index e8776a1..96ad1c9 100644 --- a/app/home/(user)/_components/home-menu-navigation.tsx +++ b/app/home/(user)/_components/home-menu-navigation.tsx @@ -1,6 +1,5 @@ import { Trans } from '@kit/ui/trans'; -import { cn } from '@kit/ui/utils'; import { AppLogo } from '~/components/app-logo'; import { ProfileAccountDropdownContainer } from '~/components/personal-account-dropdown-container'; @@ -18,7 +17,7 @@ export function HomeMenuNavigation(props: { workspace: UserWorkspace }) { return (
-
+
diff --git a/app/select-package/page.tsx b/app/select-package/page.tsx new file mode 100644 index 0000000..6e1b52a --- /dev/null +++ b/app/select-package/page.tsx @@ -0,0 +1,131 @@ +import Image from 'next/image'; +import Link from 'next/link'; + +import { CaretRightIcon } from '@radix-ui/react-icons'; +import { Scale } from 'lucide-react'; + +import { Button } from '@kit/ui/button'; +import { + Card, + CardContent, + CardDescription, + CardFooter, + CardHeader, +} from '@kit/ui/card'; + +import { createI18nServerInstance } from '~/lib/i18n/i18n.server'; +import { withI18n } from '~/lib/i18n/with-i18n'; + +import { MedReportLogo } from '../../components/med-report-logo'; +import { PackageHeader } from '../../components/package-header'; +import { ButtonTooltip } from '../../components/ui/button-tooltip'; +import pathsConfig from '../../config/paths.config'; +import ComparePackagesModal from '../home/(user)/_components/compare-packages-modal'; + +export const generateMetadata = async () => { + const { t } = await createI18nServerInstance(); + + return { + title: t('marketing:pricing'), + }; +}; + +const dummyCards = [ + { + titleKey: 'product:standard.label', + price: 40, + nrOfAnalyses: 4, + tagColor: 'bg-cyan', + descriptionKey: 'marketing:standard.description', + }, + { + titleKey: 'product:standardPlus.label', + price: 85, + nrOfAnalyses: 10, + + tagColor: 'bg-warning', + descriptionKey: 'product:standardPlus.description', + }, + { + titleKey: 'product:premium.label', + price: 140, + nrOfAnalyses: '12+', + + tagColor: 'bg-purple', + descriptionKey: 'product:premium.description', + }, +]; + +async function SelectPackagePage() { + const { t, language } = await createI18nServerInstance(); + + return ( +
+ +
+

{t('marketing:selectPackage')}

+ + {t('marketing:comparePackages')} + + + } + /> +
+
+ {dummyCards.map( + ( + { titleKey, price, nrOfAnalyses, tagColor, descriptionKey }, + index, + ) => { + return ( + + + + background + + + + {t(descriptionKey)} + + + + + + ); + }, + )} +
+
+ + + +
+
+
+
+ ); +} + +export default withI18n(SelectPackagePage); diff --git a/components/package-header.tsx b/components/package-header.tsx new file mode 100644 index 0000000..274d148 --- /dev/null +++ b/components/package-header.tsx @@ -0,0 +1,31 @@ +import { formatCurrency } from '@kit/shared/utils'; +import { Badge } from '@kit/ui/badge'; +import { cn } from '@kit/ui/utils'; + +export const PackageHeader = ({ + title, + tagColor, + analysesNr, + language, + price, +}: { + title: string; + tagColor: string; + analysesNr: string; + language: string; + price: string | number; +}) => { + return ( +
+

{title}

+

+ {formatCurrency({ + currencyCode: 'eur', + locale: language, + value: price, + })} +

+ {analysesNr} +
+ ); +}; diff --git a/components/ui/button-tooltip.tsx b/components/ui/button-tooltip.tsx new file mode 100644 index 0000000..21d1503 --- /dev/null +++ b/components/ui/button-tooltip.tsx @@ -0,0 +1,31 @@ +import { Info } from 'lucide-react'; + +import { Button } from '@kit/ui/button'; +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from '@kit/ui/tooltip'; + +export function ButtonTooltip({ + content, + className, +}: { + content?: string; + className?: string; +}) { + if (!content) return null; + return ( + + + + + + {content} + + + ); +} diff --git a/components/ui/info-tooltip.tsx b/components/ui/info-tooltip.tsx index 7883844..b0f2ed4 100644 --- a/components/ui/info-tooltip.tsx +++ b/components/ui/info-tooltip.tsx @@ -1,13 +1,27 @@ -import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@kit/ui/tooltip"; -import { Info } from "lucide-react"; +import { JSX } from 'react'; -export function InfoTooltip({ content }: { content?: string }) { +import { Info } from 'lucide-react'; + +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from '@kit/ui/tooltip'; + +export function InfoTooltip({ + content, + icon, +}: { + content?: string; + icon?: JSX.Element; +}) { if (!content) return null; return ( - + {icon || } {content} diff --git a/config/paths.config.ts b/config/paths.config.ts index f4cce84..fdb6c6d 100644 --- a/config/paths.config.ts +++ b/config/paths.config.ts @@ -13,6 +13,7 @@ const PathsSchema = z.object({ }), app: z.object({ home: z.string().min(1), + selectPackage: z.string().min(1), booking: z.string().min(1), myOrders: z.string().min(1), analysisResults: z.string().min(1), @@ -53,13 +54,14 @@ const pathsConfig = PathsSchema.parse({ accountMembers: `/home/[account]/members`, accountBillingReturn: `/home/[account]/billing/return`, joinTeam: '/join', + selectPackage: '/select-package', // these routes are added as placeholders and can be changed when the pages are added booking: '/booking', myOrders: '/my-orders', analysisResults: '/analysis-results', orderAnalysisPackage: '/order-analysis-package', orderAnalysis: '/order-analysis', - orderHealthAnalysis: '/order-health-analysis' + orderHealthAnalysis: '/order-health-analysis', }, } satisfies z.infer); diff --git a/lib/i18n/i18n.settings.ts b/lib/i18n/i18n.settings.ts index 78308fa..730259e 100644 --- a/lib/i18n/i18n.settings.ts +++ b/lib/i18n/i18n.settings.ts @@ -33,6 +33,7 @@ export const defaultI18nNamespaces = [ 'billing', 'marketing', 'dashboard', + 'product', ]; /** diff --git a/package.json b/package.json index 45a1b03..d8242ea 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,7 @@ "@marsidev/react-turnstile": "^1.1.0", "@nosecone/next": "1.0.0-beta.7", "@radix-ui/react-icons": "^1.3.2", + "@radix-ui/react-visually-hidden": "^1.2.3", "@supabase/ssr": "^0.6.1", "@supabase/supabase-js": "2.49.4", "@tanstack/react-query": "5.76.1", diff --git a/packages/billing/gateway/src/components/pricing-table.tsx b/packages/billing/gateway/src/components/pricing-table.tsx deleted file mode 100644 index d79ddbd..0000000 --- a/packages/billing/gateway/src/components/pricing-table.tsx +++ /dev/null @@ -1,519 +0,0 @@ -'use client'; - -import { useState } from 'react'; - -import Link from 'next/link'; - -import { ArrowRight, CheckCircle } from 'lucide-react'; -import { useTranslation } from 'react-i18next'; -import { z } from 'zod'; - -import { - BillingConfig, - type LineItemSchema, - getPlanIntervals, - getPrimaryLineItem, -} from '@kit/billing'; -import { Badge } from '@kit/ui/badge'; -import { Button } from '@kit/ui/button'; -import { If } from '@kit/ui/if'; -import { Trans } from '@kit/ui/trans'; -import { cn } from '@kit/ui/utils'; - -import { LineItemDetails } from './line-item-details'; -import { PlanCostDisplay } from './plan-cost-display'; - -interface Paths { - signUp: string; - return: string; -} - -type Interval = 'month' | 'year'; - -export function PricingTable({ - config, - paths, - CheckoutButtonRenderer, - redirectToCheckout = true, - displayPlanDetails = true, - alwaysDisplayMonthlyPrice = true, -}: { - config: BillingConfig; - paths: Paths; - displayPlanDetails?: boolean; - alwaysDisplayMonthlyPrice?: boolean; - redirectToCheckout?: boolean; - - CheckoutButtonRenderer?: React.ComponentType<{ - planId: string; - productId: string; - highlighted?: boolean; - }>; -}) { - const intervals = getPlanIntervals(config).filter(Boolean) as Interval[]; - const [interval, setInterval] = useState(intervals[0]!); - - // Always filter out hidden products - const visibleProducts = config.products.filter((product) => !product.hidden); - - return ( -
-
- {intervals.length > 1 ? ( - - ) : null} -
- -
- {visibleProducts.map((product) => { - const plan = product.plans.find((plan) => { - if (plan.paymentType === 'recurring') { - return plan.interval === interval; - } - - return plan; - }); - - if (!plan) { - return null; - } - - const primaryLineItem = getPrimaryLineItem(config, plan.id); - - if (!plan.custom && !primaryLineItem) { - throw new Error(`Primary line item not found for plan ${plan.id}`); - } - - return ( - - ); - })} -
-
- ); -} - -function PricingItem( - props: React.PropsWithChildren<{ - className?: string; - displayPlanDetails: boolean; - - paths: Paths; - - selectable: boolean; - - primaryLineItem: z.infer | undefined; - - redirectToCheckout?: boolean; - alwaysDisplayMonthlyPrice?: boolean; - - plan: { - id: string; - lineItems: z.infer[]; - interval?: Interval; - name?: string; - href?: string; - label?: string; - custom?: boolean; - }; - - CheckoutButton?: React.ComponentType<{ - planId: string; - productId: string; - highlighted?: boolean; - }>; - - product: { - id: string; - name: string; - currency: string; - description: string; - badge?: string; - highlighted?: boolean; - features: string[]; - }; - }>, -) { - const highlighted = props.product.highlighted ?? false; - const lineItem = props.primaryLineItem!; - const isCustom = props.plan.custom ?? false; - - // we exclude flat line items from the details since - // it doesn't need further explanation - const lineItemsToDisplay = props.plan.lineItems.filter((item) => { - return item.type !== 'flat'; - }); - - const interval = props.plan.interval as Interval; - - return ( -
- -
- - - - - -
-
- -
-
-
- - - -
-
- -
- - - } - > - - - - - - - - } - > - {(interval) => ( - - )} - - - - - / - - - - - - - - - - - - - -
- - - - } - > - {(CheckoutButton) => ( - - )} - - - - - - - -
- -
- -
- - -
- -
-
- -
- - -
- -
-
- ); -} - -function FeaturesList( - props: React.PropsWithChildren<{ - features: string[]; - highlighted: boolean; - }>, -) { - return ( -
    - {props.features.map((feature) => { - return ( - - - - ); - })} -
- ); -} - -function Price({ - children, - isMonthlyPrice = true, - displayBillingPeriod = true, -}: React.PropsWithChildren<{ - isMonthlyPrice?: boolean; - displayBillingPeriod?: boolean; -}>) { - return ( -
- - {children} - - - - - / - - - - -
- ); -} - -function ListItem({ - children, - highlighted, -}: React.PropsWithChildren<{ - highlighted: boolean; -}>) { - return ( -
  • - - - - {children} - -
  • - ); -} - -function PlanIntervalSwitcher( - props: React.PropsWithChildren<{ - intervals: Interval[]; - interval: Interval; - setInterval: (interval: Interval) => void; - }>, -) { - return ( -
    - {props.intervals.map((plan, index) => { - const selected = plan === props.interval; - - const className = cn( - 'animate-in fade-in !outline-hidden rounded-full transition-all focus:!ring-0', - { - 'border-r-transparent': index === 0, - ['hover:text-primary text-muted-foreground']: !selected, - ['cursor-default font-semibold']: selected, - ['hover:bg-initial']: !selected, - }, - ); - - return ( - - ); - })} -
    - ); -} - -function DefaultCheckoutButton( - props: React.PropsWithChildren<{ - plan: { - id: string; - name?: string | undefined; - href?: string; - buttonLabel?: string; - }; - - product: { - name: string; - }; - - paths: Paths; - redirectToCheckout?: boolean; - - highlighted?: boolean; - }>, -) { - const { t } = useTranslation('billing'); - - const signUpPath = props.paths.signUp; - - const searchParams = new URLSearchParams({ - next: props.paths.return, - plan: props.plan.id, - redirectToCheckout: props.redirectToCheckout ? 'true' : 'false', - }); - - const linkHref = - props.plan.href ?? `${signUpPath}?${searchParams.toString()}`; - - const label = props.plan.buttonLabel ?? 'common:getStartedWithPlan'; - - return ( - - - - ); -} diff --git a/packages/features/notifications/src/components/update-account-success-notification.tsx b/packages/features/notifications/src/components/update-account-success-notification.tsx index a15455b..b36c79b 100644 --- a/packages/features/notifications/src/components/update-account-success-notification.tsx +++ b/packages/features/notifications/src/components/update-account-success-notification.tsx @@ -32,7 +32,7 @@ export const UpdateAccountSuccessNotification = ({ descriptionKey="account:updateAccount:successDescription" buttonProps={{ buttonTitleKey: 'account:updateAccount:successButton', - href: pathsConfig.app.home, + href: pathsConfig.app.selectPackage, }} /> ); diff --git a/packages/ui/src/makerkit/page.tsx b/packages/ui/src/makerkit/page.tsx index 5d6ee31..f9cf333 100644 --- a/packages/ui/src/makerkit/page.tsx +++ b/packages/ui/src/makerkit/page.tsx @@ -75,7 +75,7 @@ function PageWithHeader(props: PageProps) { const { Navigation, Children, MobileNavigation } = getSlotsFromPage(props); return ( -
    +
    = ({ className, ...props }) => ( -> = ({ className, children, ...props }) => ( + React.ComponentPropsWithoutRef & { + customClose?: React.JSX.Element; + preventAutoFocus?: boolean; + } +> = ({ className, children, customClose, preventAutoFocus, ...props }) => ( e.preventDefault() : props.onOpenAutoFocus + } + onCloseAutoFocus={ + preventAutoFocus ? (e) => e.preventDefault() : props.onOpenAutoFocus + } {...props} > {children} - - - Close + + {customClose || ( + <> + + Close + + )} ); + DialogContent.displayName = DialogPrimitive.Content.displayName; const DialogHeader = ({ diff --git a/packages/ui/src/shadcn/tooltip.tsx b/packages/ui/src/shadcn/tooltip.tsx index 1ab8c1f..606b9ef 100644 --- a/packages/ui/src/shadcn/tooltip.tsx +++ b/packages/ui/src/shadcn/tooltip.tsx @@ -6,8 +6,18 @@ import * as TooltipPrimitive from '@radix-ui/react-tooltip'; import { cn } from '../lib/utils'; -const TooltipProvider = TooltipPrimitive.Provider; - +function TooltipProvider({ + delayDuration = 0, + ...props +}: React.ComponentProps) { + return ( + + ); +} const Tooltip = TooltipPrimitive.Root; const TooltipTrigger = TooltipPrimitive.Trigger; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1837337..80b71bd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -83,6 +83,9 @@ importers: '@radix-ui/react-icons': specifier: ^1.3.2 version: 1.3.2(react@19.1.0) + '@radix-ui/react-visually-hidden': + specifier: ^1.2.3 + version: 1.2.3(@types/react-dom@19.1.5(@types/react@19.1.4))(@types/react@19.1.4)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@supabase/ssr': specifier: ^0.6.1 version: 0.6.1(@supabase/supabase-js@2.49.4) @@ -13116,7 +13119,7 @@ snapshots: jest-worker@27.5.1: dependencies: - '@types/node': 24.0.3 + '@types/node': 22.15.32 merge-stream: 2.0.0 supports-color: 8.1.1 diff --git a/public/assets/card-image.png b/public/assets/card-image.png new file mode 100644 index 0000000..9c47887 Binary files /dev/null and b/public/assets/card-image.png differ diff --git a/public/locales/en/common.json b/public/locales/en/common.json index 2d18232..280e9f7 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -17,6 +17,7 @@ "imageInputLabel": "Click here to upload an image", "cancel": "Cancel", "clear": "Clear", + "close": "Close", "notFound": "Not Found", "backToHomePage": "Back to Home Page", "goBack": "Go Back", @@ -59,6 +60,10 @@ "shoppingCart": "Shopping cart", "search": "Search{{end}}", "myActions": "My actions", + "healthPackageComparison": { + "label": "Health package comparison", + "description": "Alljärgnevalt on antud eelinfo (sugu, vanus ja kehamassiindeksi) põhjal tehtud personalne terviseauditi valik. Tabelis on võimalik soovitatud terviseuuringute paketile lisada üksikuid uuringuid juurde." + }, "routes": { "home": "Home", "overview": "Overview", diff --git a/public/locales/en/marketing.json b/public/locales/en/marketing.json index a214fc2..a89e086 100644 --- a/public/locales/en/marketing.json +++ b/public/locales/en/marketing.json @@ -36,5 +36,9 @@ "contactErrorDescription": "An error occurred while sending your message. Please try again later", "footerDescription": "Here you can add a description about your company or product", "copyright": "© Copyright {{year}} {{product}}. All Rights Reserved.", - "heroSubtitle": "A simple, convenient, and quick overview of your health condition" -} + "heroSubtitle": "A simple, convenient, and quick overview of your health condition", + "selectPackage": "Select package", + "selectThisPackage": "Select this package", + "comparePackages": "Compare packages", + "notInterestedInAudit": "Currently not interested in a health audit" +} \ No newline at end of file diff --git a/public/locales/en/product.json b/public/locales/en/product.json new file mode 100644 index 0000000..e2aaf81 --- /dev/null +++ b/public/locales/en/product.json @@ -0,0 +1,43 @@ +{ + "standard": { + "label": "Standard", + "description": "Sobib, kui soovid lisaks peamistele tervisenäitajatele ülevaadet, kas organismis on olulisemaid vitamiine ja mineraalaineid piisavalt." + }, + "standardPlus": { + "label": "Standard +", + "description": "Sobib, kui soovid lisaks peamistele tervisenäitajatele ülevaadet, kas organismis on olulisemaid vitamiine ja mineraalaineid piisavalt." + }, + "premium": { + "label": "Premium", + "description": "Sobib, kui soovid lisaks peamistele tervisenäitajatele ülevaadet, kas organismis on olulisemaid vitamiine ja mineraalaineid piisavalt." + }, + "nrOfAnalyses": "{{nr}} analyses", + "clinicalBloodDraw": { + "label": "Kliiniline vereanalüüs", + "description": "Pending" + }, + "crp": { + "label": "C-reaktiivne valk (CRP)", + "description": "Pending" + }, + "ferritin": { + "label": "Ferritiin", + "description": "Pending" + }, + "vitaminD": { + "label": "D-vitamiin", + "description": "Pending" + }, + "glucose": { + "label": "Glükoos", + "description": "Pending" + }, + "alat": { + "label": "Alaniini aminotransferaas", + "description": "Pending" + }, + "ast": { + "label": "Aspartaadi aminotransferaas", + "description": "Pending" + } +} \ No newline at end of file diff --git a/public/locales/et/common.json b/public/locales/et/common.json index a224ca7..75443a0 100644 --- a/public/locales/et/common.json +++ b/public/locales/et/common.json @@ -17,6 +17,7 @@ "imageInputLabel": "Click here to upload an image", "cancel": "Cancel", "clear": "Clear", + "close": "Sulge", "notFound": "Not Found", "backToHomePage": "Back to Home Page", "goBack": "Tagasi", @@ -59,6 +60,10 @@ "shoppingCart": "Ostukorv", "search": "Otsi{{end}}", "myActions": "Minu toimingud", + "healthPackageComparison": { + "label": "Tervisepakketide võrdlus", + "description": "Alljärgnevalt on antud eelinfo (sugu, vanus ja kehamassiindeksi) põhjal tehtud personalne terviseauditi valik. Tabelis on võimalik soovitatud terviseuuringute paketile lisada üksikuid uuringuid juurde." + }, "routes": { "home": "Home", "overview": "Ülevaade", diff --git a/public/locales/et/marketing.json b/public/locales/et/marketing.json index a214fc2..4faec68 100644 --- a/public/locales/et/marketing.json +++ b/public/locales/et/marketing.json @@ -36,5 +36,9 @@ "contactErrorDescription": "An error occurred while sending your message. Please try again later", "footerDescription": "Here you can add a description about your company or product", "copyright": "© Copyright {{year}} {{product}}. All Rights Reserved.", - "heroSubtitle": "A simple, convenient, and quick overview of your health condition" -} + "heroSubtitle": "Lihtne, mugav ja kiire ülevaade oma tervisest", + "selectPackage": "Vali pakett", + "selectThisPackage": "Vali see pakett", + "comparePackages": "Võrdle pakette", + "notInterestedInAudit": "Ei soovi hetkel terviseauditit" +} \ No newline at end of file diff --git a/public/locales/et/product.json b/public/locales/et/product.json new file mode 100644 index 0000000..01876f9 --- /dev/null +++ b/public/locales/et/product.json @@ -0,0 +1,43 @@ +{ + "standard": { + "label": "Standard", + "description": "Sobib, kui soovid lisaks peamistele tervisenäitajatele ülevaadet, kas organismis on olulisemaid vitamiine ja mineraalaineid piisavalt." + }, + "standardPlus": { + "label": "Standard +", + "description": "Sobib, kui soovid lisaks peamistele tervisenäitajatele ülevaadet, kas organismis on olulisemaid vitamiine ja mineraalaineid piisavalt." + }, + "premium": { + "label": "Premium", + "description": "Sobib, kui soovid lisaks peamistele tervisenäitajatele ülevaadet, kas organismis on olulisemaid vitamiine ja mineraalaineid piisavalt." + }, + "nrOfAnalyses": "{{nr}} analüüsi", + "clinicalBloodDraw": { + "label": "Kliiniline vereanalüüs", + "description": "Pending" + }, + "crp": { + "label": "C-reaktiivne valk (CRP)", + "description": "Pending" + }, + "ferritin": { + "label": "Ferritiin", + "description": "Pending" + }, + "vitaminD": { + "label": "D-vitamiin", + "description": "Pending" + }, + "glucose": { + "label": "Glükoos", + "description": "Pending" + }, + "alat": { + "label": "Alaniini aminotransferaas", + "description": "Pending" + }, + "ast": { + "label": "Aspartaadi aminotransferaas", + "description": "Pending" + } +} \ No newline at end of file diff --git a/public/locales/ru/common.json b/public/locales/ru/common.json index 8003930..6428f91 100644 --- a/public/locales/ru/common.json +++ b/public/locales/ru/common.json @@ -17,6 +17,7 @@ "imageInputLabel": "Click here to upload an image", "cancel": "Cancel", "clear": "Clear", + "close": "Close", "notFound": "Not Found", "backToHomePage": "Back to Home Page", "goBack": "Go Back", @@ -59,6 +60,10 @@ "shoppingCart": "Shopping cart", "search": "Search{{end}}", "myActions": "My actions", + "healthPackageComparison": { + "label": "Health package comparison", + "description": "Alljärgnevalt on antud eelinfo (sugu, vanus ja kehamassiindeksi) põhjal tehtud personalne terviseauditi valik. Tabelis on võimalik soovitatud terviseuuringute paketile lisada üksikuid uuringuid juurde." + }, "routes": { "home": "Home", "overview": "Overview", diff --git a/public/locales/ru/marketing.json b/public/locales/ru/marketing.json index a214fc2..a89e086 100644 --- a/public/locales/ru/marketing.json +++ b/public/locales/ru/marketing.json @@ -36,5 +36,9 @@ "contactErrorDescription": "An error occurred while sending your message. Please try again later", "footerDescription": "Here you can add a description about your company or product", "copyright": "© Copyright {{year}} {{product}}. All Rights Reserved.", - "heroSubtitle": "A simple, convenient, and quick overview of your health condition" -} + "heroSubtitle": "A simple, convenient, and quick overview of your health condition", + "selectPackage": "Select package", + "selectThisPackage": "Select this package", + "comparePackages": "Compare packages", + "notInterestedInAudit": "Currently not interested in a health audit" +} \ No newline at end of file diff --git a/public/locales/ru/product.json b/public/locales/ru/product.json new file mode 100644 index 0000000..e2aaf81 --- /dev/null +++ b/public/locales/ru/product.json @@ -0,0 +1,43 @@ +{ + "standard": { + "label": "Standard", + "description": "Sobib, kui soovid lisaks peamistele tervisenäitajatele ülevaadet, kas organismis on olulisemaid vitamiine ja mineraalaineid piisavalt." + }, + "standardPlus": { + "label": "Standard +", + "description": "Sobib, kui soovid lisaks peamistele tervisenäitajatele ülevaadet, kas organismis on olulisemaid vitamiine ja mineraalaineid piisavalt." + }, + "premium": { + "label": "Premium", + "description": "Sobib, kui soovid lisaks peamistele tervisenäitajatele ülevaadet, kas organismis on olulisemaid vitamiine ja mineraalaineid piisavalt." + }, + "nrOfAnalyses": "{{nr}} analyses", + "clinicalBloodDraw": { + "label": "Kliiniline vereanalüüs", + "description": "Pending" + }, + "crp": { + "label": "C-reaktiivne valk (CRP)", + "description": "Pending" + }, + "ferritin": { + "label": "Ferritiin", + "description": "Pending" + }, + "vitaminD": { + "label": "D-vitamiin", + "description": "Pending" + }, + "glucose": { + "label": "Glükoos", + "description": "Pending" + }, + "alat": { + "label": "Alaniini aminotransferaas", + "description": "Pending" + }, + "ast": { + "label": "Aspartaadi aminotransferaas", + "description": "Pending" + } +} \ No newline at end of file diff --git a/styles/theme.css b/styles/theme.css index 80b4abf..2b766a7 100644 --- a/styles/theme.css +++ b/styles/theme.css @@ -52,6 +52,9 @@ --cyan: hsla(189, 94%, 43%, 1); --color-cyan: var(--cyan); + --purple: hsla(292, 84%, 61%, 1); + --color-purple: var(--purple); + /* text colors */ --color-text-foreground: var(--foreground); --color-text-primary: var(--primary);