Spaces:
Sleeping
Sleeping
Upload 12 files
Browse files- .gitignore +32 -0
- .prettierignore +8 -0
- .prettierrc +6 -0
- AGENTS.md +10 -0
- README.md +34 -0
- bun.lock +0 -0
- bunfig.toml +7 -0
- components.json +22 -0
- eslint.config.js +40 -0
- package.json +89 -0
- tsconfig.json +30 -0
- vite.config.ts +15 -0
.gitignore
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Logs
|
| 2 |
+
logs
|
| 3 |
+
*.log
|
| 4 |
+
npm-debug.log*
|
| 5 |
+
yarn-debug.log*
|
| 6 |
+
yarn-error.log*
|
| 7 |
+
pnpm-debug.log*
|
| 8 |
+
lerna-debug.log*
|
| 9 |
+
|
| 10 |
+
node_modules
|
| 11 |
+
dist
|
| 12 |
+
dist-ssr
|
| 13 |
+
.output
|
| 14 |
+
.vinxi
|
| 15 |
+
.tanstack/**
|
| 16 |
+
.nitro
|
| 17 |
+
*.local
|
| 18 |
+
|
| 19 |
+
# Wrangler / Cloudflare
|
| 20 |
+
.wrangler/
|
| 21 |
+
.dev.vars
|
| 22 |
+
|
| 23 |
+
# Editor directories and files
|
| 24 |
+
.vscode/*
|
| 25 |
+
!.vscode/extensions.json
|
| 26 |
+
.idea
|
| 27 |
+
.DS_Store
|
| 28 |
+
*.suo
|
| 29 |
+
*.ntvs*
|
| 30 |
+
*.njsproj
|
| 31 |
+
*.sln
|
| 32 |
+
*.sw?
|
.prettierignore
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
node_modules
|
| 2 |
+
dist
|
| 3 |
+
.output
|
| 4 |
+
.vinxi
|
| 5 |
+
pnpm-lock.yaml
|
| 6 |
+
package-lock.json
|
| 7 |
+
bun.lock
|
| 8 |
+
routeTree.gen.ts
|
.prettierrc
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"printWidth": 100,
|
| 3 |
+
"semi": true,
|
| 4 |
+
"singleQuote": false,
|
| 5 |
+
"trailingComma": "all"
|
| 6 |
+
}
|
AGENTS.md
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!-- LOVABLE:BEGIN -->
|
| 2 |
+
> [!IMPORTANT]
|
| 3 |
+
> This project is connected to [Lovable](https://lovable.dev). Avoid rewriting
|
| 4 |
+
> published git history — force pushing, or rebasing/amending/squashing commits
|
| 5 |
+
> that are already pushed — as it rewrites history on Lovable's side and the
|
| 6 |
+
> user will likely lose their project history.
|
| 7 |
+
>
|
| 8 |
+
> Commits you push to the connected branch sync back to Lovable and show up in
|
| 9 |
+
> the editor, so keep the branch in a working state.
|
| 10 |
+
<!-- LOVABLE:END -->
|
README.md
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Tatting Canvas Studio
|
| 2 |
+
|
| 3 |
+
Build an interactive web app for Tatting pattern design (Editor Studio) similar to tatting-studio.lovable.app. Needs:
|
| 4 |
+
|
| 5 |
+
Grid background with snap (10px).
|
| 6 |
+
|
| 7 |
+
Left sidebar with Tatting elements (Rings with picots: Ring 4, Ring 6, Ring 8... and Arcs).
|
| 8 |
+
|
| 9 |
+
Interactive Canvas: drag and drop elements, rotate, change thread color, duplicate, mirror (symmetry).
|
| 10 |
+
|
| 11 |
+
Right sidebar for color palette (gold, silver, purple, etc.).
|
| 12 |
+
|
| 13 |
+
Export canvas to PNG button. Make UI clean, modern, and tablet touch-friendly with large buttons.
|
| 14 |
+
|
| 15 |
+
This project was built with [Lovable](https://lovable.dev).
|
| 16 |
+
|
| 17 |
+
## Build with Lovable
|
| 18 |
+
|
| 19 |
+
Continue developing this project in the [Lovable editor](https://lovable.dev/projects/b3b0a826-a5e5-4624-a36e-e855eda92ed4).
|
| 20 |
+
|
| 21 |
+
- **Ship faster**: describe what you want to build and Lovable handles the code.
|
| 22 |
+
- **Stay in sync**: every change made in Lovable is committed straight to this repository.
|
| 23 |
+
- **Full ownership**: this code is yours. Push to `main` on GitHub and your changes sync back into Lovable, ready for your next prompt.
|
| 24 |
+
|
| 25 |
+
## Development
|
| 26 |
+
|
| 27 |
+
Prefer working locally? You need Node.js and npm — [install with nvm](https://github.com/nvm-sh/nvm#installing-and-updating).
|
| 28 |
+
|
| 29 |
+
```sh
|
| 30 |
+
git clone <this-repository-url>
|
| 31 |
+
cd <repository-name>
|
| 32 |
+
npm i
|
| 33 |
+
npm run dev
|
| 34 |
+
```
|
bun.lock
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
bunfig.toml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[install]
|
| 2 |
+
saveTextLockfile = true
|
| 3 |
+
# 24h supply-chain guard: skip package versions published less than a day ago.
|
| 4 |
+
minimumReleaseAge = 86400
|
| 5 |
+
# Each entry bypasses the 24h guard for one package — confirm with the user
|
| 6 |
+
# before adding any.
|
| 7 |
+
minimumReleaseAgeExcludes = ["@lovable.dev/vite-tanstack-config", "@lovable.dev/mcp-js", "@lovable.dev/vite-plugin-dev-server-bridge", "@lovable.dev/vite-plugin-hmr-gate", "@lovable.dev/email-js", "@lovable.dev/webhooks-js"]
|
components.json
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"$schema": "https://ui.shadcn.com/schema.json",
|
| 3 |
+
"style": "new-york",
|
| 4 |
+
"rsc": false,
|
| 5 |
+
"tsx": true,
|
| 6 |
+
"tailwind": {
|
| 7 |
+
"css": "src/styles.css",
|
| 8 |
+
"baseColor": "slate",
|
| 9 |
+
"cssVariables": true,
|
| 10 |
+
"prefix": ""
|
| 11 |
+
},
|
| 12 |
+
"iconLibrary": "lucide",
|
| 13 |
+
"rtl": false,
|
| 14 |
+
"aliases": {
|
| 15 |
+
"components": "@/components",
|
| 16 |
+
"utils": "@/lib/utils",
|
| 17 |
+
"ui": "@/components/ui",
|
| 18 |
+
"lib": "@/lib",
|
| 19 |
+
"hooks": "@/hooks"
|
| 20 |
+
},
|
| 21 |
+
"registries": {}
|
| 22 |
+
}
|
eslint.config.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import js from "@eslint/js";
|
| 2 |
+
import eslintPluginPrettier from "eslint-plugin-prettier/recommended";
|
| 3 |
+
import globals from "globals";
|
| 4 |
+
import reactHooks from "eslint-plugin-react-hooks";
|
| 5 |
+
import reactRefresh from "eslint-plugin-react-refresh";
|
| 6 |
+
import tseslint from "typescript-eslint";
|
| 7 |
+
|
| 8 |
+
export default tseslint.config(
|
| 9 |
+
{ ignores: ["dist", ".output", ".vinxi"] },
|
| 10 |
+
{
|
| 11 |
+
extends: [js.configs.recommended, ...tseslint.configs.recommended],
|
| 12 |
+
files: ["**/*.{ts,tsx}"],
|
| 13 |
+
languageOptions: {
|
| 14 |
+
ecmaVersion: 2020,
|
| 15 |
+
globals: globals.browser,
|
| 16 |
+
},
|
| 17 |
+
plugins: {
|
| 18 |
+
"react-hooks": reactHooks,
|
| 19 |
+
"react-refresh": reactRefresh,
|
| 20 |
+
},
|
| 21 |
+
rules: {
|
| 22 |
+
...reactHooks.configs.recommended.rules,
|
| 23 |
+
"no-restricted-imports": [
|
| 24 |
+
"error",
|
| 25 |
+
{
|
| 26 |
+
paths: [
|
| 27 |
+
{
|
| 28 |
+
name: "server-only",
|
| 29 |
+
message:
|
| 30 |
+
"TanStack Start does not use the Next.js `server-only` package. Rename the module to `*.server.ts` or mark it with `@tanstack/react-start/server-only`.",
|
| 31 |
+
},
|
| 32 |
+
],
|
| 33 |
+
},
|
| 34 |
+
],
|
| 35 |
+
"react-refresh/only-export-components": ["warn", { allowConstantExport: true }],
|
| 36 |
+
"@typescript-eslint/no-unused-vars": "off",
|
| 37 |
+
},
|
| 38 |
+
},
|
| 39 |
+
eslintPluginPrettier,
|
| 40 |
+
);
|
package.json
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"name": "tanstack_start_ts",
|
| 3 |
+
"private": true,
|
| 4 |
+
"sideEffects": false,
|
| 5 |
+
"type": "module",
|
| 6 |
+
"scripts": {
|
| 7 |
+
"dev": "vite dev",
|
| 8 |
+
"build": "vite build",
|
| 9 |
+
"build:dev": "vite build --mode development",
|
| 10 |
+
"preview": "vite preview",
|
| 11 |
+
"lint": "eslint .",
|
| 12 |
+
"format": "prettier --write ."
|
| 13 |
+
},
|
| 14 |
+
"dependencies": {
|
| 15 |
+
"@hookform/resolvers": "^5.2.2",
|
| 16 |
+
"@radix-ui/react-accordion": "^1.2.12",
|
| 17 |
+
"@radix-ui/react-alert-dialog": "^1.1.15",
|
| 18 |
+
"@radix-ui/react-aspect-ratio": "^1.1.8",
|
| 19 |
+
"@radix-ui/react-avatar": "^1.1.11",
|
| 20 |
+
"@radix-ui/react-checkbox": "^1.3.3",
|
| 21 |
+
"@radix-ui/react-collapsible": "^1.1.12",
|
| 22 |
+
"@radix-ui/react-context-menu": "^2.2.16",
|
| 23 |
+
"@radix-ui/react-dialog": "^1.1.15",
|
| 24 |
+
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
| 25 |
+
"@radix-ui/react-hover-card": "^1.1.15",
|
| 26 |
+
"@radix-ui/react-label": "^2.1.8",
|
| 27 |
+
"@radix-ui/react-menubar": "^1.1.16",
|
| 28 |
+
"@radix-ui/react-navigation-menu": "^1.2.14",
|
| 29 |
+
"@radix-ui/react-popover": "^1.1.15",
|
| 30 |
+
"@radix-ui/react-progress": "^1.1.8",
|
| 31 |
+
"@radix-ui/react-radio-group": "^1.3.8",
|
| 32 |
+
"@radix-ui/react-scroll-area": "^1.2.10",
|
| 33 |
+
"@radix-ui/react-select": "^2.2.6",
|
| 34 |
+
"@radix-ui/react-separator": "^1.1.8",
|
| 35 |
+
"@radix-ui/react-slider": "^1.3.6",
|
| 36 |
+
"@radix-ui/react-slot": "^1.2.4",
|
| 37 |
+
"@radix-ui/react-switch": "^1.2.6",
|
| 38 |
+
"@radix-ui/react-tabs": "^1.1.13",
|
| 39 |
+
"@radix-ui/react-toggle": "^1.1.10",
|
| 40 |
+
"@radix-ui/react-toggle-group": "^1.1.11",
|
| 41 |
+
"@radix-ui/react-tooltip": "^1.2.8",
|
| 42 |
+
"@tailwindcss/vite": "^4.2.1",
|
| 43 |
+
"@tanstack/react-query": "^5.101.1",
|
| 44 |
+
"@tanstack/react-router": "^1.170.18",
|
| 45 |
+
"@tanstack/react-start": "^1.168.32",
|
| 46 |
+
"@tanstack/router-plugin": "^1.168.23",
|
| 47 |
+
"class-variance-authority": "^0.7.1",
|
| 48 |
+
"clsx": "^2.1.1",
|
| 49 |
+
"cmdk": "^1.1.1",
|
| 50 |
+
"date-fns": "^4.1.0",
|
| 51 |
+
"embla-carousel-react": "^8.6.0",
|
| 52 |
+
"fabric": "^7.4.0",
|
| 53 |
+
"input-otp": "^1.4.2",
|
| 54 |
+
"jspdf": "^4.2.1",
|
| 55 |
+
"lucide-react": "^0.575.0",
|
| 56 |
+
"react": "^19.2.0",
|
| 57 |
+
"react-day-picker": "^9.14.0",
|
| 58 |
+
"react-dom": "^19.2.0",
|
| 59 |
+
"react-hook-form": "^7.71.2",
|
| 60 |
+
"react-resizable-panels": "^4.6.5",
|
| 61 |
+
"recharts": "^2.15.4",
|
| 62 |
+
"sonner": "^2.0.7",
|
| 63 |
+
"tailwind-merge": "^3.5.0",
|
| 64 |
+
"tailwindcss": "^4.2.1",
|
| 65 |
+
"tw-animate-css": "^1.3.4",
|
| 66 |
+
"vaul": "^1.1.2",
|
| 67 |
+
"vite-tsconfig-paths": "^6.0.2",
|
| 68 |
+
"zod": "^3.24.2"
|
| 69 |
+
},
|
| 70 |
+
"devDependencies": {
|
| 71 |
+
"@eslint/js": "^9.32.0",
|
| 72 |
+
"@lovable.dev/vite-tanstack-config": "^2.8.5",
|
| 73 |
+
"@types/node": "^22.16.5",
|
| 74 |
+
"@types/react": "^19.2.0",
|
| 75 |
+
"@types/react-dom": "^19.2.0",
|
| 76 |
+
"@vitejs/plugin-react": "^5.2.0",
|
| 77 |
+
"eslint": "^9.32.0",
|
| 78 |
+
"eslint-config-prettier": "^10.1.1",
|
| 79 |
+
"eslint-plugin-prettier": "^5.2.6",
|
| 80 |
+
"eslint-plugin-react-hooks": "^5.2.0",
|
| 81 |
+
"eslint-plugin-react-refresh": "^0.4.20",
|
| 82 |
+
"globals": "^15.15.0",
|
| 83 |
+
"nitro": "3.0.260603-beta",
|
| 84 |
+
"prettier": "^3.7.3",
|
| 85 |
+
"typescript": "^5.8.3",
|
| 86 |
+
"typescript-eslint": "^8.56.1",
|
| 87 |
+
"vite": "^8.1.5"
|
| 88 |
+
}
|
| 89 |
+
}
|
tsconfig.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"include": ["src/**/*.ts", "src/**/*.tsx", "vite.config.ts", "eslint.config.js"],
|
| 3 |
+
"compilerOptions": {
|
| 4 |
+
"target": "ES2022",
|
| 5 |
+
"jsx": "react-jsx",
|
| 6 |
+
"module": "ESNext",
|
| 7 |
+
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
| 8 |
+
"types": ["vite/client"],
|
| 9 |
+
|
| 10 |
+
"moduleResolution": "Bundler",
|
| 11 |
+
"allowImportingTsExtensions": true,
|
| 12 |
+
"verbatimModuleSyntax": false,
|
| 13 |
+
"noEmit": true,
|
| 14 |
+
|
| 15 |
+
"skipLibCheck": true,
|
| 16 |
+
"strict": true,
|
| 17 |
+
"noUnusedLocals": false,
|
| 18 |
+
"noUnusedParameters": false,
|
| 19 |
+
"noFallthroughCasesInSwitch": true,
|
| 20 |
+
"noImplicitOverride": true,
|
| 21 |
+
"noImplicitReturns": true,
|
| 22 |
+
"noPropertyAccessFromIndexSignature": true,
|
| 23 |
+
"noUncheckedIndexedAccess": true,
|
| 24 |
+
"exactOptionalPropertyTypes": true,
|
| 25 |
+
"noUncheckedSideEffectImports": true,
|
| 26 |
+
"paths": {
|
| 27 |
+
"@/*": ["./src/*"]
|
| 28 |
+
}
|
| 29 |
+
}
|
| 30 |
+
}
|
vite.config.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// @lovable.dev/vite-tanstack-config already includes the following — do NOT add them manually
|
| 2 |
+
// or the app will break with duplicate plugins:
|
| 3 |
+
// - TanStack devtools (dev-only, first), tanstackStart, viteReact, tailwindcss, tsConfigPaths,
|
| 4 |
+
// nitro (build-only using cloudflare as a default target), VITE_* env injection, @ path alias,
|
| 5 |
+
// React/TanStack dedupe, error logger plugins, and sandbox detection (port/host/strictPort).
|
| 6 |
+
// You can pass additional config via defineConfig({ vite: { ... }, etc... }) if needed.
|
| 7 |
+
import { defineConfig } from "@lovable.dev/vite-tanstack-config";
|
| 8 |
+
|
| 9 |
+
export default defineConfig({
|
| 10 |
+
tanstackStart: {
|
| 11 |
+
// Redirect TanStack Start's bundled server entry to src/server.ts (our SSR error wrapper).
|
| 12 |
+
// nitro/vite builds from this
|
| 13 |
+
server: { entry: "server" },
|
| 14 |
+
},
|
| 15 |
+
});
|