Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ todos.json
.env.*
certs/
*.gen.ts
project.inlang
1 change: 1 addition & 0 deletions eslint-configs/rules.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ const i18next = { 'i18next/no-literal-string': 'error' };
const tanstackQuery = {
'@tanstack/query/exhaustive-deps': 'warn',
'@tanstack/query/stable-query-client': 'warn',
'@tanstack/query/no-rest-destructuring': 'warn',
};
const tanstackRouter = {
'@tanstack/router/create-route-property-order': 'warn',
Expand Down
7,360 changes: 3,500 additions & 3,860 deletions package-lock.json

Large diffs are not rendered by default.

128 changes: 56 additions & 72 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,95 +11,79 @@
"build:stag": "NODE_ENV=staging vite build --mode staging",
"serve": "NODE_ENV=development vite preview",
"deploy": "wrangler deploy",
"test": "vitest",
"test:unit": "vitest src",
"test": "vitest run",
"test:watch": "vitest watch",
"test:unit": "vitest run --exclude src/__tests__",
"test:watch:unit": "vitest watch --exclude src/__tests__",
"test:component": "vitest run --dir src/__tests__/component",
"test:watch:component": "vitest watch --dir src/__tests__/component",
"test:integration": "vitest run --dir src/__tests__/integration",
"test:watch:integration": "vitest watch --dir src/__tests__/integration",
"lint": "eslint",
"format": "prettier --write ."
},
"dependencies": {
"@cloudflare/vite-plugin": "^1.17.1",
"@customcads/react-sdk": "^1.13.4-beta.2",
"@icons-pack/react-simple-icons": "^13.8.0",
"@microsoft/signalr": "^9.0.6",
"@radix-ui/react-alert-dialog": "^1.1.15",
"@radix-ui/react-checkbox": "^1.3.3",
"@radix-ui/react-collapsible": "^1.1.12",
"@radix-ui/react-dialog": "^1.1.15",
"@radix-ui/react-dropdown-menu": "^2.1.16",
"@radix-ui/react-label": "^2.1.7",
"@radix-ui/react-popover": "^1.1.15",
"@radix-ui/react-progress": "^1.1.8",
"@radix-ui/react-radio-group": "^1.3.8",
"@radix-ui/react-scroll-area": "^1.2.10",
"@radix-ui/react-select": "^2.2.6",
"@radix-ui/react-separator": "^1.1.8",
"@radix-ui/react-slider": "^1.3.6",
"@radix-ui/react-slot": "^1.2.4",
"@radix-ui/react-switch": "^1.2.6",
"@radix-ui/react-tabs": "^1.1.13",
"@radix-ui/react-tooltip": "^1.2.8",
"@stripe/react-stripe-js": "^5.2.0",
"@stripe/stripe-js": "^8.1.0",
"@tanstack/react-form": "^1.27.7",
"@tanstack/react-pacer": "^0.18.0",
"@tanstack/react-query": "^5.90.12",
"@tanstack/react-ranger": "0.0.4",
"@tanstack/react-router": "^1.141.2",
"@tanstack/react-router-ssr-query": "^1.141.2",
"@tanstack/react-start": "^1.141.3",
"@tanstack/react-store": "^0.8.0",
"@tanstack/react-virtual": "^3.13.13",
"@tanstack/router-plugin": "^1.141.2",
"@tanstack/store": "^0.7.7",
"axios": "^1.13.2",
"@cloudflare/vite-plugin": "^1.39.0",
"@customcads/react-sdk": "^1.13.5-beta.2",
"@icons-pack/react-simple-icons": "^13.11.1",
"@microsoft/signalr": "^10.0.0",
"@tanstack/react-form": "^1.32.1",
"@tanstack/react-pacer": "^0.22.1",
"@tanstack/react-query": "^5.100.10",
"@tanstack/react-router": "^1.170.8",
"@tanstack/react-router-ssr-query": "^1.167.0",
"@tanstack/react-start": "^1.168.14",
"@tanstack/react-store": "^0.11.0",
"@tanstack/react-virtual": "^3.13.26",
"@tanstack/router-plugin": "^1.168.11",
"@tanstack/store": "^0.11.0",
"axios": "^1.16.1",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"cmdk": "^1.1.1",
"i18next": "^25.6.0",
"js-cookie": "^3.0.5",
"lucide-react": "^0.544.0",
"i18next": "^26.3.0",
"js-cookie": "^3.0.7",
"lucide-react": "^1.16.0",
"radix-ui": "^1.4.3",
"react": "^19.2.6",
"react-dom": "^19.2.6",
"react-i18next": "^16.1.5",
"react-phone-number-input": "^3.4.12",
"tailwind-merge": "^3.0.2",
"three": "^0.180.0",
"react-i18next": "^17.0.8",
"tailwind-merge": "^3.6.0",
"three": "^0.184.0",
"tw-animate-css": "^1.3.6",
"uuid": "^13.0.0",
"web-vitals": "^5.1.0",
"uuid": "^14.0.0",
"web-vitals": "^5.2.0",
"wrangler": "^4.54.0",
"zod": "^4.1.11"
"zod": "^4.4.3"
},
"devDependencies": {
"@tailwindcss/vite": "^4.1.11",
"@tanstack/devtools-vite": "^0.3.12",
"@tanstack/eslint-plugin-query": "^5.83.1",
"@tanstack/eslint-plugin-router": "^1.130.12",
"@tanstack/react-devtools": "^0.8.4",
"@tanstack/react-query-devtools": "^5.91.1",
"@tanstack/react-router-devtools": "^1.141.2",
"@tailwindcss/vite": "^4.3.0",
"@tanstack/devtools-vite": "^0.7.0",
"@tanstack/eslint-plugin-query": "^5.100.14",
"@tanstack/eslint-plugin-router": "^1.162.0",
"@tanstack/react-devtools": "^0.10.5",
"@tanstack/react-query-devtools": "^5.100.10",
"@tanstack/react-router-devtools": "^1.167.0",
"@types/js-cookie": "^3.0.6",
"@types/node": "^20.19.9",
"@types/react": "^19.2.14",
"@types/node": "^25.9.1",
"@types/react": "^19.2.15",
"@types/react-dom": "^19.2.3",
"@types/three": "^0.172.0",
"@typescript-eslint/eslint-plugin": "^8.38.0",
"@typescript-eslint/parser": "^8.38.0",
"@vitejs/plugin-react": "^5.0.4",
"@vitest/eslint-plugin": "^1.3.23",
"@types/three": "^0.184.1",
"@typescript-eslint/eslint-plugin": "^8.60.0",
"@typescript-eslint/parser": "^8.60.0",
"@vitejs/plugin-react": "^6.0.2",
"@vitest/eslint-plugin": "^1.6.18",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-i18next": "^6.1.3",
"eslint-plugin-prettier": "^5.5.3",
"eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-i18next": "^6.1.4",
"eslint-plugin-prettier": "^5.5.5",
"eslint-plugin-react-hooks": "^7.1.1",
"eslint-plugin-react-i18next": "^1.1.0",
"eslint-plugin-react-refresh": "^0.4.20",
"jsdom": "^27.0.0",
"eslint-plugin-react-refresh": "^0.5.2",
"jsdom": "^28.1.0",
"prettier": "^3.6.2",
"tailwindcss": "^4.1.11",
"ts-node": "^10.9.2",
"typescript": "^5.8.3",
"vite": "^7.1.7",
"vite-tsconfig-paths": "^5.1.4",
"vitest": "^3.2.4"
"tailwindcss": "^4.3.0",
"typescript": "^5.9.3",
"vite": "^8.0.14",
"vitest": "^4.1.7"
}
}
18 changes: 9 additions & 9 deletions src/app/components/alert/index.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
import { useFormTranslations } from '@/app/hooks/locales/translations/components';
import * as alert from '@/app/components/ui/alert';
import { alert } from '@/app/components/ui/';

type Props = { success: string | false; error?: string };
const Alert = ({ success, error }: Props) => {
const tState = useFormTranslations('state');

if (error) {
return (
<alert.Alert variant='destructive'>
<alert.AlertTitle>{tState('error')}</alert.AlertTitle>
<alert.AlertDescription>{error}</alert.AlertDescription>
</alert.Alert>
<alert.Root variant='destructive'>
<alert.Title>{tState('error')}</alert.Title>
<alert.Description>{error}</alert.Description>
</alert.Root>
);
}

if (success) {
return (
<alert.Alert variant='success'>
<alert.AlertTitle>{tState('success')}</alert.AlertTitle>
<alert.AlertDescription>{success}</alert.AlertDescription>
</alert.Alert>
<alert.Root variant='success'>
<alert.Title>{tState('success')}</alert.Title>
<alert.Description>{success}</alert.Description>
</alert.Root>
);
}
};
Expand Down
5 changes: 2 additions & 3 deletions src/app/components/cad/editor/hooks/useEditorThreeJS.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { useRef } from 'react';
import * as THREE from 'three';
import { CalculateCad } from '@/types/threejs';
import { getEnv } from '@/lib/isomorphic/env';
import { updateMaterial } from '@/lib/cad/material';
import { boxSize } from '@/lib/cad/three-js';
import { getEnv } from '@/lib/isomorphic';
import { updateMaterial, boxSize } from '@/lib/cad';
import * as editor from '@/app/stores/editor';
import * as calculate3D from '@/app/utils/calculate-3D';

Expand Down
6 changes: 3 additions & 3 deletions src/app/components/cad/editor/index.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { useQuery } from '@customcads/react-sdk';
import { AppError } from '@/types/errors';
import { getCadType } from '@/lib/cad/get-type';
import { getCadType } from '@/lib/cad';
import { useEditorStore } from '@/app/hooks/stores/useEditorStore';
import { useCadBlobUrl } from '@/app/hooks/features/cads/useCadBlobUrl';
import { useTextures } from '@/app/hooks/features/materials/useTextures';
import Loader from '@/app/components/loading';
import EditorThreeJS from './threejs';

type EditorCadProps = { cadId: string };
const EditorCad = ({ cadId }: EditorCadProps) => {
type Props = { cadId: string };
const EditorCad = ({ cadId }: Props) => {
const { blobUrl: cadBlobUrl, progress } = useCadBlobUrl(cadId, 'Product');
const { data: cad } = useQuery(({ cads }) => cads.single({ id: cadId }));

Expand Down
2 changes: 1 addition & 1 deletion src/app/components/cad/editor/threejs.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useEffect } from 'react';
import * as THREE from 'three';
import { Coordinates } from '@customcads/react-sdk';
import { type AllowedType } from '@/lib/cad/get-type';
import { type AllowedType } from '@/lib/cad';
import { useThreeJS } from '@/hooks/headless/useThreeJS';
import type { Material } from '@/app/types/material';
import { useEditorStore } from '@/app/hooks/stores/useEditorStore';
Expand Down
2 changes: 1 addition & 1 deletion src/app/components/cad/gallery/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useQuery } from '@customcads/react-sdk';
import { getCadType } from '@/lib/cad/get-type';
import { getCadType } from '@/lib/cad';
import { useCadBlobUrl } from '@/app/hooks/features/cads/useCadBlobUrl';
import Loader from '@/app/components/loading';
import GalleryThreeJS from './threejs';
Expand Down
2 changes: 1 addition & 1 deletion src/app/components/cad/gallery/threejs.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Coordinates } from '@customcads/react-sdk';
import { type AllowedType } from '@/lib/cad/get-type';
import { type AllowedType } from '@/lib/cad';
import { useThreeJS } from '@/hooks/headless/useThreeJS';
import Model from '../model';

Expand Down
4 changes: 2 additions & 2 deletions src/app/components/cad/model.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { Ref } from 'react';
import Loader from '../loading';

type ModelProps = {
type Props = {
threejs: {
ref: Ref<HTMLDivElement>;
progress: number;
};
};

const Model = ({ threejs: { ref, progress } }: ModelProps) => [
const Model = ({ threejs: { ref, progress } }: Props) => [
progress < 1 && <Loader key='loader' progress={progress} isCad />,
<div key='model' ref={ref} className='h-full w-full' />,
];
Expand Down
15 changes: 7 additions & 8 deletions src/app/components/clipboard.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { useState } from 'react';
import { ClipboardPen } from 'lucide-react';
import { cn } from '@/lib/utils/tailwindcss';
import { cn } from '@/lib/utils';
import { useLayoutTranslations } from '@/app/hooks/locales/translations/components';
import { Tooltip, TooltipContent, TooltipTrigger } from './ui/tooltip';
import { Button } from './ui/button';
import { Button, tooltip } from './ui';

type Props = { value: string };
const Clipboard = ({ value }: Props) => {
Expand All @@ -20,8 +19,8 @@ const Clipboard = ({ value }: Props) => {
};

return (
<Tooltip>
<TooltipTrigger className='relative flex flex-col items-center'>
<tooltip.Root>
<tooltip.Trigger className='relative flex flex-col items-center'>
<Button
type='button'
variant='ghost'
Expand All @@ -46,9 +45,9 @@ const Clipboard = ({ value }: Props) => {
>
{tUi('clipboard-message')}
</span>
</TooltipTrigger>
<TooltipContent>{tUi('clipboard-label')}</TooltipContent>
</Tooltip>
</tooltip.Trigger>
<tooltip.Content>{tUi('clipboard-label')}</tooltip.Content>
</tooltip.Root>
);
};

Expand Down
6 changes: 3 additions & 3 deletions src/app/components/error/index.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { Link } from '@tanstack/react-router';
import { AppErrorFields } from '@/types/errors';
import { cn } from '@/lib/utils/tailwindcss';
import { cn } from '@/lib/utils';
import { useCommonTranslations } from '@/app/hooks/locales/translations/common';
import * as page from '@/app/utils/page';

type ErrorPageProps = {
type Props = {
status: 400 | 401 | 403 | 404 | null;
error?: AppErrorFields;
};
const ErrorPage = ({ status, error }: ErrorPageProps) => {
const ErrorPage = ({ status, error }: Props) => {
const tError = useCommonTranslations('errors');
const { title, message, tip } = error ?? {
title: tError(`${status ?? 'default'}_title`),
Expand Down
12 changes: 4 additions & 8 deletions src/app/components/fields/field.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
import { type AnyFieldApi } from '@tanstack/react-form';
import { Children } from '@/types/react';
import { Children, ClassName } from '@/types/react';
import { useFormTranslations } from '@/app/hooks/locales/translations/components';
import { Label } from '../ui/label';
import { Label } from '@/app/components/ui';
import FormInput from './input';
import PasswordInput from './password';
import Error from './error';

type Props = Children & {
api: AnyFieldApi;
isSubmitted: boolean;
canEdit?: boolean;
className?: string;
};
type Props = Children &
ClassName & { api: AnyFieldApi; isSubmitted: boolean; canEdit?: boolean };
const FormField = ({ api, isSubmitted, canEdit, ...props }: Props) => {
const tLabels = useFormTranslations('labels');
const tPlaceholders = useFormTranslations('placeholders');
Expand Down
2 changes: 1 addition & 1 deletion src/app/components/fields/input.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { AnyFieldApi } from '@tanstack/react-form';
import { Input } from '@/app/components/ui/input';
import { Input } from '@/app/components/ui';

type Props = { api: AnyFieldApi } & React.ComponentProps<typeof Input>;
const FormInput = ({ api, ...props }: Props) => (
Expand Down
5 changes: 2 additions & 3 deletions src/app/components/fields/radio.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { RadioGroupItem } from '@/app/components/ui/radio-group';
import { Label } from '@/app/components/ui/label';
import { Label, radioGroup } from '@/app/components/ui';

type Props = { value: string; label?: string };
const RadioField = ({ value, label }: Props) => (
<div className='flex items-center gap-x-2'>
<RadioGroupItem id={value} value={value} className='w-4 h-4' />
<radioGroup.Item id={value} value={value} className='w-4 h-4' />
<Label htmlFor={value} className='text-base'>
{label}
</Label>
Expand Down
Loading
Loading