{"id":51095899,"url":"https://github.com/resoul/studio.old","last_synced_at":"2026-06-24T06:35:09.142Z","repository":{"id":232681166,"uuid":"784939159","full_name":"resoul/studio.old","owner":"resoul","description":null,"archived":false,"fork":false,"pushed_at":"2026-04-12T10:13:50.000Z","size":29766,"stargazers_count":5,"open_issues_count":4,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-04-24T22:37:23.846Z","etag":null,"topics":["automation","contacts","email","email-templates","forms","react","tags","tailwindcss"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/resoul.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-04-10T21:35:50.000Z","updated_at":"2026-04-24T20:52:24.000Z","dependencies_parsed_at":null,"dependency_job_id":"21b18f80-08af-4e63-9b4b-618e65338885","html_url":"https://github.com/resoul/studio.old","commit_stats":null,"previous_names":["resoul/airlance-core","resoul/gifted","resoul/email-builder","resoul/studio"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/resoul/studio.old","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/resoul%2Fstudio.old","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/resoul%2Fstudio.old/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/resoul%2Fstudio.old/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/resoul%2Fstudio.old/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/resoul","download_url":"https://codeload.github.com/resoul/studio.old/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/resoul%2Fstudio.old/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34720921,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-24T02:00:07.484Z","response_time":106,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["automation","contacts","email","email-templates","forms","react","tags","tailwindcss"],"created_at":"2026-06-24T06:35:07.432Z","updated_at":"2026-06-24T06:35:09.131Z","avatar_url":"https://github.com/resoul.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Email Builder\n\nA drag-and-drop email template builder built with React 18, TypeScript, and Vite.\n\n## Stack\n\n- **React 18** + **TypeScript** + **Vite**\n- **Tailwind CSS** + **shadcn/ui** (Radix primitives)\n- **dnd-kit** for drag \u0026 drop\n- **react-router-dom** v6\n- **@tanstack/react-query**\n- **Vitest** + **@testing-library/react** for tests\n\n## Getting Started\n\nThe only requirement is Node.js \u0026 npm — [install with nvm](https://github.com/nvm-sh/nvm#installing-and-updating).\n\n```sh\n# Clone the repository\ngit clone \u003cYOUR_GIT_URL\u003e\n\n# Navigate to the project directory\ncd \u003cYOUR_PROJECT_NAME\u003e\n\n# Install dependencies\nnpm i\n\n# Start the development server\nnpm run dev\n```\n\n## Available Scripts\n\n| Command | Description |\n|---|---|\n| `npm run dev` | Start dev server with HMR |\n| `npm run build` | Production build |\n| `npm run build:dev` | Development build |\n| `npm run lint` | Run ESLint |\n| `npm run preview` | Preview production build |\n| `npm test` | Run all tests (single pass) |\n| `npm run test:watch` | Run tests in watch mode |\n\n## Features\n\n- **Block palette** — Drag or click to add: Heading, Text, Image, Button, Hero, Product Card, Coupon, Survey/Rating, Timer, Video, Divider, Spacer, HTML, Social, IF/ELSE Conditional\n- **Multi-column rows** — 1, 2, or 3 column layouts with drag-and-drop reordering\n- **Inline editing** — Click any text block to edit in place with a floating rich-text toolbar (bold, italic, underline, links, font size/family, lists, alignment, AI rewrite, personalisation variables)\n- **Properties panel** — Full property editing for every block type\n- **Image editor** — Crop, adjust (brightness/contrast/saturation/blur), AI background removal, AI upscale, stock photo browser (Unsplash)\n- **Personalisation** — Insert `{{variable}}` merge tags and IF/ELSE conditional blocks\n- **Undo / Redo** — Full history with Ctrl+Z / Ctrl+Shift+Z\n- **Desktop / Mobile preview toggle**\n- **AI template generation** (mock) and starter templates\n- **Upload HTML** — Import an existing HTML email and parse it into editable blocks\n- **Export** — Download email-safe HTML or copy to clipboard; optional Google Fonts injection\n- **Internationalisation** — English, Russian, Ukrainian, Italian, Spanish, French\n\n## Project Structure\n\n```\nsrc/\n├── modules/         # Feature-based modules (campaigns, automations, dashboard, etc.)\n├── components/      # Shared components (ui, screen-loader, etc.)\n├── providers/       # Global context providers (modules-provider.tsx)\n├── layout/          # App shell, sidebar, navigation\n├── styles/          # Global styles (index.css)\n├── config/          # Fonts, social networks, personalisation variables, i18n\n├── data/            # Starter email templates\n├── hooks/           # Global/Shared hooks\n├── types/           # All TypeScript types\n└── utils/           # Global utilities\n\ntests/               # Mirror of src/ structure; run with Vitest\n```\n\n## Configuration\n\n### Unsplash Stock Photos\n\nAdd your free Unsplash API key to `.env` to enable live search:\n\n```\nVITE_UNSPLASH_ACCESS_KEY=your_key_here\n```\n\nGet a free key at \u003chttps://unsplash.com/developers\u003e. Without a key, a curated library of 20 images is shown.\n\n### Image Storage\n\nBy default, edited images are stored as base64 data URIs. To switch to a server upload, edit `src/config/image-storage.ts`:\n\n```ts\nexport const IMAGE_STORAGE_CONFIG: ImageStorageConfig = {\n    driver: 'server',\n    serverEndpoint: 'https://your-upload-endpoint.com/upload',\n};\n```\n\n### Adding a New Block Type\n\nSee the step-by-step guide in [`AGENTS.md`](./AGENTS.md#adding-a-new-block-type).\n\n### Adding a New Social Network\n\nAppend one entry to `SOCIAL_NETWORK_CONFIG` in `src/config/social-networks.ts` — no other files need changing. See [`AGENTS.md`](./AGENTS.md#adding-a-new-social-network).\n\n### Adding a New Language\n\nSee [`AGENTS.md`](./AGENTS.md#adding-a-new-language).\n\n## Testing\n\nTests live in `tests/` and mirror the `src/` structure.\n\n```sh\nnpm test          # single run\nnpm run test:watch  # watch mode\n```\n\nCoverage areas include utility functions (`parseHtml`, `exportHtml`, AI mocks), hooks (`useEmailBuilder`, `useBlockOps`, `useTemplateHistory`), inline editor helpers (positioning, formatting, toolbar state, keyboard handling), and component-level tests (block renderers, modals, context menus).\n\n## Deployment\n\nBuild the project and serve the `dist/` folder from any static host:\n\n```sh\nnpm run build\n# then upload dist/ to your host of choice\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fresoul%2Fstudio.old","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fresoul%2Fstudio.old","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fresoul%2Fstudio.old/lists"}