3 Commits

Author SHA1 Message Date
ab0834149d wip 2025-07-18 16:10:13 +03:00
5487242bbe feat(MED-100): db types 2025-07-17 12:55:59 +03:00
7ccc45ce77 feat(MED-100): show toast on delete 2025-07-17 10:44:05 +03:00
20 changed files with 174 additions and 185 deletions

22
.env
View File

@@ -53,5 +53,23 @@ NEXT_PUBLIC_DEFAULT_LOCALE=et
NEXT_PUBLIC_TEAM_NAVIGATION_STYLE=custom
NEXT_PUBLIC_USER_NAVIGATION_STYLE=custom
# MEDUSA
NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY=
#### MEDUSA
#NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY=pk_0ec86252438b38ce18d5601f7877e4395d7e0a6afa8687dfea8d37af33015633
#MEDUSA_BACKEND_URL=http://5.181.51.38:9000
NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY=pk_e23a820689a07d55aa0a0ad187268559f5d6288ecb0768ff4520516285bdef84
MEDUSA_BACKEND_URL=http://localhost:9000
# NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY=pk_068d930c33fea53608a410d84a51935f6ce2ccec5bef8e0ecf75eaee602ac486
# MEDUSA_BACKEND_URL=https://backoffice-test.medreport.ee:443
#### MONTONIO
NEXT_PUBLIC_MONTONIO_ACCESS_KEY=7da5d7fa-3383-4997-9435-46aa818f4ead
MONTONIO_SECRET_KEY=rNZkzwxOiH93mzkdV53AvhSsbGidrgO2Kl5lE/IT7cvo
MONTONIO_API_URL=https://sandbox-stargate.montonio.com
#### SUPABASE
# NEXT_PUBLIC_SUPABASE_URL=https://oqsdacktkhmbylmzstjq.supabase.co
# NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Im9xc2RhY2t0a2htYnlsbXpzdGpxIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NDY1MjgxMjMsImV4cCI6MjA2MjEwNDEyM30.LdHCTWxijFmhXdnT9KVuLRAVbtSwY7OO-oLtpd8GmO0
# SUPABASE_SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Im9xc2RhY2t0a2htYnlsbXpzdGpxIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImlhdCI6MTc0NjUyODEyMywiZXhwIjoyMDYyMTA0MTIzfQ.KVcnkZ21Pd0XkJho23dZqFHawVTLQqfvF7l2RxsELLk
NEXT_PUBLIC_SUPABASE_URL=http://5.181.51.38:54321
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0
SUPABASE_SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp7fsn3W0YpN81IU

View File

@@ -2,7 +2,7 @@
# These values are only used when running the app in development mode.
# SUPABASE
NEXT_PUBLIC_SUPABASE_URL=http://127.0.0.1:54321
NEXT_PUBLIC_SUPABASE_URL=http://5.181.51.38:54321
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0
SUPABASE_SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp7fsn3W0YpN81IU

View File

@@ -38,6 +38,9 @@ export const POST = enhanceRouteHandler(
const body = await request.json();
const namespace = 'montonio.verify-token';
const activeCartId = request.cookies.get('_medusa_cart_id')?.value;
console.info('cart id', activeCartId);
try {
const { token } = BodySchema.parse(body);
@@ -58,6 +61,12 @@ export const POST = enhanceRouteHandler(
algorithms: ['HS256'],
}) as MontonioOrderToken;
const [, cartId] = decoded.merchantReferenceDisplay.split(':');
console.info('active cart id parsed', {cartId, activeCartId, decoded:decoded.merchantReferenceDisplay});
if (cartId !== activeCartId) {
throw new Error('Invalid cart id');
}
logger.info(
{
name: namespace,

View File

@@ -0,0 +1,48 @@
"use client";
import { Trash } from "lucide-react";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { toast } from 'sonner';
import { deleteLineItem } from "@lib/data/cart";
import { Spinner } from "@medusajs/icons";
const CartItemDelete = ({
id,
children,
}: {
id: string;
children?: React.ReactNode;
}) => {
const [isDeleting, setIsDeleting] = useState(false);
const { t } = useTranslation();
const handleDelete = async () => {
setIsDeleting(true);
const promise = async () => {
await deleteLineItem(id);
};
toast.promise(promise, {
success: t(`cart:items.delete.success`),
loading: t(`cart:items.delete.loading`),
error: t(`cart:items.delete.error`),
});
};
return (
<div className="flex items-center justify-between text-small-regular">
<button
className="flex gap-x-1 text-ui-fg-subtle hover:text-ui-fg-base cursor-pointer"
onClick={() => handleDelete()}
>
{isDeleting ? <Spinner className="animate-spin" /> : <Trash />}
<span>{children}</span>
</button>
</div>
);
};
export default CartItemDelete;

View File

@@ -1,14 +1,13 @@
"use client"
import { HttpTypes } from "@medusajs/types"
import DeleteButton from "@modules/common/components/delete-button"
import { useTranslation } from "react-i18next"
import {
TableCell,
TableRow,
} from '@kit/ui/table';
import { formatCurrency } from "@/packages/shared/src/utils"
import { Trash } from "lucide-react"
import CartItemDelete from "./cart-item-delete";
export default function CartItem({ item, currencyCode }: {
item: HttpTypes.StoreCartLineItem
@@ -49,7 +48,7 @@ export default function CartItem({ item, currencyCode }: {
<TableCell className="text-right px-6">
<span className="flex gap-x-1 justify-end w-[60px]">
<DeleteButton id={item.id} data-testid="product-delete-button" Icon={<Trash />} />
<CartItemDelete id={item.id} />
</span>
</TableCell>
</TableRow>

View File

@@ -21,7 +21,7 @@ export default function CartItems({ cart, items, productColumnLabelKey }: {
return (
<Table className="rounded-lg border border-separate">
<TableHeader className="text-ui-fg-subtle txt-medium-plus">
<TableRow className="">
<TableRow>
<TableHead className="px-6">
<Trans i18nKey={productColumnLabelKey} />
</TableHead>

View File

@@ -1,6 +1,6 @@
'use client';
import { useSearchParams } from 'next/navigation';
import { useRouter, useSearchParams } from 'next/navigation';
import { useEffect, useState } from 'react';
import { Alert, AlertDescription, AlertTitle } from '@kit/ui/alert';
@@ -8,6 +8,7 @@ import { Button } from '@kit/ui/button';
import { Trans } from '@kit/ui/trans';
import { placeOrder } from "@lib/data/cart"
import Link from 'next/link';
import GlobalLoader from '../../loading';
enum Status {
LOADING = 'LOADING',
@@ -15,12 +16,19 @@ enum Status {
}
export function MontonioCheckoutCallback() {
const router = useRouter();
const [status, setStatus] = useState<Status>(Status.LOADING);
const [isFinalized, setIsFinalized] = useState(false);
const searchParams = useSearchParams();
useEffect(() => {
if (isFinalized) {
return;
}
const token = searchParams.get('order-token');
if (!token) {
//router.push('/home/cart');
return;
}
@@ -35,6 +43,7 @@ export function MontonioCheckoutCallback() {
},
body: JSON.stringify({ token }),
});
setIsFinalized(true);
if (!response.ok) {
const body = await response.json();
@@ -44,9 +53,14 @@ export function MontonioCheckoutCallback() {
const body = await response.json();
const paymentStatus = body.status as string;
if (paymentStatus === 'PAID') {
await placeOrder();
try {
await placeOrder();
} catch (e) {
console.error("Error placing order", e);
router.push('/home/cart');
}
} else {
setStatus(Status.ERROR);
throw new Error('Payment failed or pending');
}
} catch (e) {
console.error("Error verifying token", e);
@@ -55,7 +69,7 @@ export function MontonioCheckoutCallback() {
}
void verifyToken();
}, [searchParams]);
}, [searchParams, isFinalized]);
if (status === Status.ERROR) {
return (
@@ -83,5 +97,5 @@ export function MontonioCheckoutCallback() {
);
}
return null;
return <GlobalLoader />;
}

View File

@@ -67,7 +67,7 @@ export default function CartTotals({ order }: {
</div>
<div className="h-px w-full border-b border-gray-200 my-4" />
<div className="flex items-center justify-between text-ui-fg-base mb-2 txt-medium ">
<span><Trans i18nKey="cart:orderConfirmed.total" /></span>
<span className="font-bold"><Trans i18nKey="cart:orderConfirmed.total" /></span>
<span
className="txt-xlarge-plus"
data-testid="cart-total"

View File

@@ -1,6 +1,7 @@
import { Trans } from '@kit/ui/trans';
import { PageBody, PageHeader } from '@kit/ui/page';
import { StoreOrder } from "@medusajs/types"
import Divider from "@modules/common/components/divider"
import CartTotals from "./cart-totals"
import OrderDetails from "./order-details"
@@ -14,8 +15,10 @@ export default async function OrderCompleted({
return (
<PageBody>
<PageHeader title={<Trans i18nKey="cart:orderConfirmed.title" />} />
<Divider />
<div className="grid grid-cols-1 small:grid-cols-[1fr_360px] gap-x-40 lg:px-4 gap-y-6">
<OrderDetails order={order} />
<Divider />
<OrderItems order={order} />
<CartTotals order={order} />
</div>

View File

@@ -11,13 +11,13 @@ export default function OrderItem({ item, currencyCode }: {
}) {
return (
<TableRow className="w-full" data-testid="product-row">
{/* <TableCell className="!pl-0 p-4 w-24">
{/* <TableCell className="px-6 w-24">
<div className="flex w-16">
<Thumbnail thumbnail={item.thumbnail} size="square" />
</div>
</TableCell> */}
<TableCell className="text-left">
<TableCell className="text-left px-6">
<span
className="txt-medium-plus text-ui-fg-base"
data-testid="product-name"
@@ -27,8 +27,8 @@ export default function OrderItem({ item, currencyCode }: {
<LineItemOptions variant={item.variant} data-testid="product-variant" />
</TableCell>
<TableCell className="!pr-0">
<span className="!pr-0 flex flex-col items-end h-full justify-center">
<TableCell className="px-6">
<span className="flex flex-col items-end h-full justify-center">
<span className="flex gap-x-1 ">
<span className="text-ui-fg-muted">
{item.quantity}x{" "}

View File

@@ -2,7 +2,6 @@ import repeat from "@lib/util/repeat"
import { StoreOrder } from "@medusajs/types"
import { Table, TableBody } from "@kit/ui/table"
import Divider from "@modules/common/components/divider"
import SkeletonLineItem from "@modules/skeletons/components/skeleton-line-item"
import OrderItem from "./order-item"
import { Heading } from "@kit/ui/heading"
@@ -19,8 +18,7 @@ export default function OrderItems({ order }: {
<Trans i18nKey="cart:orderConfirmed.summary" />
</Heading>
<div className="flex flex-col">
<Divider className="!mb-0" />
<Table>
<Table className="rounded-lg border border-separate">
<TableBody data-testid="products-table">
{items?.length
? items

View File

@@ -3,6 +3,7 @@
import { useState } from 'react';
import { useTranslation } from 'react-i18next';
import Image from 'next/image';
import { useRouter } from 'next/navigation';
import {
Card,
@@ -34,8 +35,9 @@ export default function SelectAnalysisPackage({
analysisPackage: StoreProduct
countryCode: string,
}) {
const router = useRouter();
const { t, i18n: { language } } = useTranslation();
const [isAddingToCart, setIsAddingToCart] = useState(false);
const handleSelect = async (selectedVariant: StoreProductVariant) => {
if (!selectedVariant?.id) return null
@@ -46,6 +48,7 @@ export default function SelectAnalysisPackage({
countryCode,
});
setIsAddingToCart(false);
router.push('/home/cart');
}
const titleKey = analysisPackage.title;

View File

@@ -21,10 +21,10 @@ export async function register() {
* @param err
*/
export const onRequestError: Instrumentation.onRequestError = async (err) => {
const { getServerMonitoringService } = await import('@kit/monitoring/server');
// const { getServerMonitoringService } = await import('@kit/monitoring/server');
const service = await getServerMonitoringService();
// const service = await getServerMonitoringService();
await service.ready();
await service.captureException(err as Error);
// await service.ready();
// await service.captureException(err as Error);
};

View File

@@ -73,7 +73,7 @@ export async function handleNavigateToPayment({ language }: { language: string }
currency: cart.currency_code.toUpperCase(),
description: `Order from Medreport`,
locale: language,
merchantReference: `${account.id}:${Date.now()}`,
merchantReference: `${account.id}:${cart.id}:${Date.now()}`,
});
const { error } = await supabase

View File

@@ -84,7 +84,7 @@ export class MontonioWebhookHandlerService
}, `Received Montonio webhook event`);
if (event.paymentStatus === 'PAID') {
const accountId = event.merchantReferenceDisplay.split(':')[0];
const [accountId] = event.merchantReferenceDisplay.split(':');
if (!accountId) {
throw new Error('Invalid merchant reference');
}

View File

@@ -44,7 +44,7 @@ export async function retrieveCart(cartId?: string) {
},
headers,
next,
cache: "force-cache",
//cache: "force-cache",
})
.then(({ cart }) => cart)
.catch(() => null);
@@ -396,7 +396,7 @@ export async function placeOrder(cartId?: string) {
const id = cartId || (await getCartId());
if (!id) {
return;
throw new Error("No existing cart found when placing an order");
}
const headers = {

View File

@@ -116,7 +116,29 @@ export type Database = {
status?: string
}
Relationships: []
}
},
cart_entries: {
Row: {
id: number
account_id: string
cart_id: string
operation: string
variant_id: string
comment: string | null
created_at: string
changed_by: string | null
}
Insert: {
id: number
account_id: string
cart_id: string
operation: string
variant_id: string
comment: string | null
created_at: string
changed_by: string | null
}
},
}
Views: {
[_ in never]: never

171
pnpm-lock.yaml generated
View File

@@ -10,7 +10,7 @@ importers:
dependencies:
'@edge-csrf/nextjs':
specifier: 2.5.3-cloudflare-rc1
version: 2.5.3-cloudflare-rc1(next@15.3.5(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))
version: 2.5.3-cloudflare-rc1(next@15.3.2(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))
'@hookform/resolvers':
specifier: ^5.1.1
version: 5.1.1(react-hook-form@7.58.0(react@19.1.0))
@@ -73,7 +73,7 @@ importers:
version: 0.0.10(@supabase/postgrest-js@1.19.4)(@supabase/supabase-js@2.49.4)
'@makerkit/data-loader-supabase-nextjs':
specifier: ^1.2.5
version: 1.2.5(@supabase/postgrest-js@1.19.4)(@supabase/supabase-js@2.49.4)(@tanstack/react-query@5.76.1(react@19.1.0))(next@15.3.5(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0)
version: 1.2.5(@supabase/postgrest-js@1.19.4)(@supabase/supabase-js@2.49.4)(@tanstack/react-query@5.76.1(react@19.1.0))(next@15.3.2(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0)
'@marsidev/react-turnstile':
specifier: ^1.1.0
version: 1.1.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
@@ -88,7 +88,7 @@ importers:
version: 4.0.17(@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)(typescript@5.8.3)
'@nosecone/next':
specifier: 1.0.0-beta.7
version: 1.0.0-beta.7(next@15.3.5(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))
version: 1.0.0-beta.7(next@15.3.2(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))
'@radix-ui/react-icons':
specifier: ^1.3.2
version: 1.3.2(react@19.1.0)
@@ -129,11 +129,11 @@ importers:
specifier: ^0.510.0
version: 0.510.0(react@19.1.0)
next:
specifier: 15.3.5
version: 15.3.5(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
specifier: 15.3.2
version: 15.3.2(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
next-sitemap:
specifier: ^4.2.3
version: 4.2.3(next@15.3.5(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))
version: 4.2.3(next@15.3.2(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))
next-themes:
specifier: 0.4.6
version: 0.4.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
@@ -2224,9 +2224,6 @@ packages:
'@next/env@15.3.2':
resolution: {integrity: sha512-xURk++7P7qR9JG1jJtLzPzf0qEvqCN0A/T3DXf8IPMKo9/6FfjxtEffRJIIew/bIL4T3C2jLLqBor8B/zVlx6g==}
'@next/env@15.3.5':
resolution: {integrity: sha512-7g06v8BUVtN2njAX/r8gheoVffhiKFVt4nx74Tt6G4Hqw9HCLYQVx/GkH2qHvPtAHZaUNZ0VXAa0pQP6v1wk7g==}
'@next/env@15.4.0-canary.128':
resolution: {integrity: sha512-o1L2iI/6zHvYQo4hwwf7a3eu5lEOLBChl79Apreub/EwUFHAoRHfmaMYlVfk4uWo3XUNvMRxOG+dRAWmxn4mJQ==}
@@ -2242,12 +2239,6 @@ packages:
cpu: [arm64]
os: [darwin]
'@next/swc-darwin-arm64@15.3.5':
resolution: {integrity: sha512-lM/8tilIsqBq+2nq9kbTW19vfwFve0NR7MxfkuSUbRSgXlMQoJYg+31+++XwKVSXk4uT23G2eF/7BRIKdn8t8w==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [darwin]
'@next/swc-darwin-arm64@15.4.0-canary.128':
resolution: {integrity: sha512-3W+dQHTO4baj4iMfWCcXDrrpYsQmuLE1rqLjx3UjMswrJx5DSOPre2haAH5W6CtLvTVEB8x/xCCzJ8ZlqfF5CA==}
engines: {node: '>= 10'}
@@ -2260,12 +2251,6 @@ packages:
cpu: [x64]
os: [darwin]
'@next/swc-darwin-x64@15.3.5':
resolution: {integrity: sha512-WhwegPQJ5IfoUNZUVsI9TRAlKpjGVK0tpJTL6KeiC4cux9774NYE9Wu/iCfIkL/5J8rPAkqZpG7n+EfiAfidXA==}
engines: {node: '>= 10'}
cpu: [x64]
os: [darwin]
'@next/swc-darwin-x64@15.4.0-canary.128':
resolution: {integrity: sha512-BlXLOSoc9Xubx/ZRB1k76Akd7ildo98Ypn+IglZiapheAfA//euQZUHZXD66ZVyWHYqdCEw7vg4EzpnXA8wlpg==}
engines: {node: '>= 10'}
@@ -2278,12 +2263,6 @@ packages:
cpu: [arm64]
os: [linux]
'@next/swc-linux-arm64-gnu@15.3.5':
resolution: {integrity: sha512-LVD6uMOZ7XePg3KWYdGuzuvVboxujGjbcuP2jsPAN3MnLdLoZUXKRc6ixxfs03RH7qBdEHCZjyLP/jBdCJVRJQ==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
'@next/swc-linux-arm64-gnu@15.4.0-canary.128':
resolution: {integrity: sha512-ZUnD74X5yTa/De0s1x/SG6Rv+MGEx6nuz+Th3qmKOUCmwzlxE4UBF7+Vwti4Wg8aEEzxebJUR8WRrmWwvmui8g==}
engines: {node: '>= 10'}
@@ -2296,12 +2275,6 @@ packages:
cpu: [arm64]
os: [linux]
'@next/swc-linux-arm64-musl@15.3.5':
resolution: {integrity: sha512-k8aVScYZ++BnS2P69ClK7v4nOu702jcF9AIHKu6llhHEtBSmM2zkPGl9yoqbSU/657IIIb0QHpdxEr0iW9z53A==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
'@next/swc-linux-arm64-musl@15.4.0-canary.128':
resolution: {integrity: sha512-pMJ79xdufMeLuOyHY6F0LE/GgHRZZiLVch7YntB7dNZ8HZbV+br4UzssAgr3JfAGyuRnNY0dWgreKwGyGDNSfw==}
engines: {node: '>= 10'}
@@ -2314,12 +2287,6 @@ packages:
cpu: [x64]
os: [linux]
'@next/swc-linux-x64-gnu@15.3.5':
resolution: {integrity: sha512-2xYU0DI9DGN/bAHzVwADid22ba5d/xrbrQlr2U+/Q5WkFUzeL0TDR963BdrtLS/4bMmKZGptLeg6282H/S2i8A==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
'@next/swc-linux-x64-gnu@15.4.0-canary.128':
resolution: {integrity: sha512-33xXJqrbQO/qNO1n9tLbz6o38j7bs4VnOMmWVHPZH9IAHA99gHFThUZZ4TXgVa8Yj6lgIOLb7MuymaN55FZeZA==}
engines: {node: '>= 10'}
@@ -2332,12 +2299,6 @@ packages:
cpu: [x64]
os: [linux]
'@next/swc-linux-x64-musl@15.3.5':
resolution: {integrity: sha512-TRYIqAGf1KCbuAB0gjhdn5Ytd8fV+wJSM2Nh2is/xEqR8PZHxfQuaiNhoF50XfY90sNpaRMaGhF6E+qjV1b9Tg==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
'@next/swc-linux-x64-musl@15.4.0-canary.128':
resolution: {integrity: sha512-WJv6LPLKJXqvHTaX6WgliI9enlgm4tpwDE6pL619zgGSI5HXHrDsr4LzlDCD7rmuG+n937umVFESmUrnwTTrGw==}
engines: {node: '>= 10'}
@@ -2350,12 +2311,6 @@ packages:
cpu: [arm64]
os: [win32]
'@next/swc-win32-arm64-msvc@15.3.5':
resolution: {integrity: sha512-h04/7iMEUSMY6fDGCvdanKqlO1qYvzNxntZlCzfE8i5P0uqzVQWQquU1TIhlz0VqGQGXLrFDuTJVONpqGqjGKQ==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [win32]
'@next/swc-win32-arm64-msvc@15.4.0-canary.128':
resolution: {integrity: sha512-97Wrx1M3MJSGbiNNbscb/W6avnRCp/9NX9vNTp58caYxk7U7S2e3HJoWS8yeHW9193ci5kHAIBfNDr/GvFws7A==}
engines: {node: '>= 10'}
@@ -2368,12 +2323,6 @@ packages:
cpu: [x64]
os: [win32]
'@next/swc-win32-x64-msvc@15.3.5':
resolution: {integrity: sha512-5fhH6fccXxnX2KhllnGhkYMndhOiLOLEiVGYjP2nizqeGWkN10sA9taATlXwake2E2XMvYZjjz0Uj7T0y+z1yw==}
engines: {node: '>= 10'}
cpu: [x64]
os: [win32]
'@next/swc-win32-x64-msvc@15.4.0-canary.128':
resolution: {integrity: sha512-NbpGc9eZjQkjwDst5WsAlv+GFKayojuy7sz+01FJ6og8LXRJvzMCTh5uFTdaHIZr47RpZvewIlJW7mjWyvAHjg==}
engines: {node: '>= 10'}
@@ -7873,27 +7822,6 @@ packages:
sass:
optional: true
next@15.3.5:
resolution: {integrity: sha512-RkazLBMMDJSJ4XZQ81kolSpwiCt907l0xcgcpF4xC2Vml6QVcPNXW0NQRwQ80FFtSn7UM52XN0anaw8TEJXaiw==}
engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0}
hasBin: true
peerDependencies:
'@opentelemetry/api': ^1.1.0
'@playwright/test': ^1.41.2
babel-plugin-react-compiler: '*'
react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0
react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0
sass: ^1.3.0
peerDependenciesMeta:
'@opentelemetry/api':
optional: true
'@playwright/test':
optional: true
babel-plugin-react-compiler:
optional: true
sass:
optional: true
next@15.4.0-canary.128:
resolution: {integrity: sha512-Oo1GjM7ToTkus3mEMnKI93NpFt3KgtTnVDyINHrvX/rjdtEHiabNQhgowOqv84h8uLfatV+vsy7gMkYR+UsV/A==}
engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0}
@@ -9802,9 +9730,9 @@ snapshots:
'@discoveryjs/json-ext@0.5.7': {}
'@edge-csrf/nextjs@2.5.3-cloudflare-rc1(next@15.3.5(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))':
'@edge-csrf/nextjs@2.5.3-cloudflare-rc1(next@15.3.2(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))':
dependencies:
next: 15.3.5(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
next: 15.3.2(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
'@emnapi/core@1.4.3':
dependencies:
@@ -10411,16 +10339,6 @@ snapshots:
transitivePeerDependencies:
- '@supabase/postgrest-js'
'@makerkit/data-loader-supabase-nextjs@1.2.5(@supabase/postgrest-js@1.19.4)(@supabase/supabase-js@2.49.4)(@tanstack/react-query@5.76.1(react@19.1.0))(next@15.3.5(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0)':
dependencies:
'@makerkit/data-loader-supabase-core': 0.0.10(@supabase/postgrest-js@1.19.4)(@supabase/supabase-js@2.49.4)
'@supabase/supabase-js': 2.49.4
'@tanstack/react-query': 5.76.1(react@19.1.0)
next: 15.3.5(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
react: 19.1.0
transitivePeerDependencies:
- '@supabase/postgrest-js'
'@markdoc/markdoc@0.4.0(@types/react@19.1.4)(react@19.1.0)':
optionalDependencies:
'@types/markdown-it': 12.2.3
@@ -10540,8 +10458,6 @@ snapshots:
'@next/env@15.3.2': {}
'@next/env@15.3.5': {}
'@next/env@15.4.0-canary.128': {}
'@next/eslint-plugin-next@15.0.3':
@@ -10555,72 +10471,48 @@ snapshots:
'@next/swc-darwin-arm64@15.3.2':
optional: true
'@next/swc-darwin-arm64@15.3.5':
optional: true
'@next/swc-darwin-arm64@15.4.0-canary.128':
optional: true
'@next/swc-darwin-x64@15.3.2':
optional: true
'@next/swc-darwin-x64@15.3.5':
optional: true
'@next/swc-darwin-x64@15.4.0-canary.128':
optional: true
'@next/swc-linux-arm64-gnu@15.3.2':
optional: true
'@next/swc-linux-arm64-gnu@15.3.5':
optional: true
'@next/swc-linux-arm64-gnu@15.4.0-canary.128':
optional: true
'@next/swc-linux-arm64-musl@15.3.2':
optional: true
'@next/swc-linux-arm64-musl@15.3.5':
optional: true
'@next/swc-linux-arm64-musl@15.4.0-canary.128':
optional: true
'@next/swc-linux-x64-gnu@15.3.2':
optional: true
'@next/swc-linux-x64-gnu@15.3.5':
optional: true
'@next/swc-linux-x64-gnu@15.4.0-canary.128':
optional: true
'@next/swc-linux-x64-musl@15.3.2':
optional: true
'@next/swc-linux-x64-musl@15.3.5':
optional: true
'@next/swc-linux-x64-musl@15.4.0-canary.128':
optional: true
'@next/swc-win32-arm64-msvc@15.3.2':
optional: true
'@next/swc-win32-arm64-msvc@15.3.5':
optional: true
'@next/swc-win32-arm64-msvc@15.4.0-canary.128':
optional: true
'@next/swc-win32-x64-msvc@15.3.2':
optional: true
'@next/swc-win32-x64-msvc@15.3.5':
optional: true
'@next/swc-win32-x64-msvc@15.4.0-canary.128':
optional: true
@@ -10638,9 +10530,9 @@ snapshots:
'@nolyfill/is-core-module@1.0.39': {}
'@nosecone/next@1.0.0-beta.7(next@15.3.5(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))':
'@nosecone/next@1.0.0-beta.7(next@15.3.2(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))':
dependencies:
next: 15.3.5(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
next: 15.3.2(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
nosecone: 1.0.0-beta.7
'@opentelemetry/api-logs@0.50.0':
@@ -17759,7 +17651,7 @@ snapshots:
eslint: 8.10.0
eslint-import-resolver-node: 0.3.9
eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.33.1(eslint@8.10.0)(typescript@5.8.3))(eslint@8.10.0))(eslint@8.10.0)
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.33.1(eslint@8.10.0)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.10.0)
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.33.1(eslint@8.10.0)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.33.1(eslint@8.10.0)(typescript@5.8.3))(eslint@8.10.0))(eslint@8.10.0))(eslint@8.10.0)
eslint-plugin-jsx-a11y: 6.10.2(eslint@8.10.0)
eslint-plugin-react: 7.37.5(eslint@8.10.0)
eslint-plugin-react-hooks: 5.2.0(eslint@8.10.0)
@@ -17779,7 +17671,7 @@ snapshots:
eslint: 9.28.0(jiti@2.4.2)
eslint-import-resolver-node: 0.3.9
eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.32.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.0(jiti@2.4.2)))(eslint@9.28.0(jiti@2.4.2))
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.28.0(jiti@2.4.2))
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.32.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.0(jiti@2.4.2)))(eslint@9.28.0(jiti@2.4.2)))(eslint@9.28.0(jiti@2.4.2))
eslint-plugin-jsx-a11y: 6.10.2(eslint@9.28.0(jiti@2.4.2))
eslint-plugin-react: 7.37.5(eslint@9.28.0(jiti@2.4.2))
eslint-plugin-react-hooks: 5.2.0(eslint@9.28.0(jiti@2.4.2))
@@ -17815,7 +17707,7 @@ snapshots:
tinyglobby: 0.2.14
unrs-resolver: 1.7.11
optionalDependencies:
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.28.0(jiti@2.4.2))
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.32.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.0(jiti@2.4.2)))(eslint@9.28.0(jiti@2.4.2)))(eslint@9.28.0(jiti@2.4.2))
transitivePeerDependencies:
- supports-color
@@ -17830,7 +17722,7 @@ snapshots:
tinyglobby: 0.2.14
unrs-resolver: 1.7.11
optionalDependencies:
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.33.1(eslint@8.10.0)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.10.0)
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.33.1(eslint@8.10.0)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.33.1(eslint@8.10.0)(typescript@5.8.3))(eslint@8.10.0))(eslint@8.10.0))(eslint@8.10.0)
transitivePeerDependencies:
- supports-color
@@ -17856,7 +17748,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.33.1(eslint@8.10.0)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@8.10.0):
eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.33.1(eslint@8.10.0)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.33.1(eslint@8.10.0)(typescript@5.8.3))(eslint@8.10.0))(eslint@8.10.0))(eslint@8.10.0):
dependencies:
'@rtsao/scc': 1.1.0
array-includes: 3.1.9
@@ -17885,7 +17777,7 @@ snapshots:
- eslint-import-resolver-webpack
- supports-color
eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.28.0(jiti@2.4.2)):
eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.32.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.0(jiti@2.4.2)))(eslint@9.28.0(jiti@2.4.2)))(eslint@9.28.0(jiti@2.4.2)):
dependencies:
'@rtsao/scc': 1.1.0
array-includes: 3.1.9
@@ -19356,13 +19248,13 @@ snapshots:
neo-async@2.6.2: {}
next-sitemap@4.2.3(next@15.3.5(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)):
next-sitemap@4.2.3(next@15.3.2(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)):
dependencies:
'@corex/deepmerge': 4.0.43
'@next/env': 13.5.11
fast-glob: 3.3.3
minimist: 1.2.8
next: 15.3.5(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
next: 15.3.2(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
next-themes@0.4.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0):
dependencies:
@@ -19423,33 +19315,6 @@ snapshots:
- '@babel/core'
- babel-plugin-macros
next@15.3.5(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0):
dependencies:
'@next/env': 15.3.5
'@swc/counter': 0.1.3
'@swc/helpers': 0.5.15
busboy: 1.6.0
caniuse-lite: 1.0.30001723
postcss: 8.4.31
react: 19.1.0
react-dom: 19.1.0(react@19.1.0)
styled-jsx: 5.1.6(react@19.1.0)
optionalDependencies:
'@next/swc-darwin-arm64': 15.3.5
'@next/swc-darwin-x64': 15.3.5
'@next/swc-linux-arm64-gnu': 15.3.5
'@next/swc-linux-arm64-musl': 15.3.5
'@next/swc-linux-x64-gnu': 15.3.5
'@next/swc-linux-x64-musl': 15.3.5
'@next/swc-win32-arm64-msvc': 15.3.5
'@next/swc-win32-x64-msvc': 15.3.5
'@opentelemetry/api': 1.9.0
babel-plugin-react-compiler: 19.1.0-rc.2
sharp: 0.34.2
transitivePeerDependencies:
- '@babel/core'
- babel-plugin-macros
next@15.4.0-canary.128(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0):
dependencies:
'@next/env': 15.4.0-canary.128

View File

@@ -35,6 +35,11 @@
},
"services": {
"productColumnLabel": "Service name"
},
"delete": {
"success": "Item removed from cart",
"loading": "Removing item from cart",
"error": "Failed to remove item from cart"
}
},
"orderConfirmed": {

View File

@@ -36,11 +36,16 @@
},
"services": {
"productColumnLabel": "Teenuse nimi"
},
"delete": {
"success": "Toode eemaldatud ostukorvist",
"loading": "Toote eemaldamine ostukorvist",
"error": "Toote eemaldamine ostukorvist ebaõnnestus"
}
},
"orderConfirmed": {
"title": "Tellimus on edukalt esitatud",
"summary": "Summa",
"summary": "Teenused",
"subtotal": "Vahesumma",
"taxes": "Maksud",
"giftCard": "Kinkekaart",