├── public ├── _redirects ├── hi.gif ├── logo.png ├── favicon.ico ├── profile.jpg ├── favicon-32x32.jpg ├── favicon-64x64.jpg ├── icon-192x192.png ├── icon-512x512.png ├── manifest.json └── placeholder.svg ├── src ├── vite-env.d.ts ├── components │ ├── ui │ │ ├── use-toast.ts │ │ ├── aspect-ratio.tsx │ │ ├── skeleton.tsx │ │ ├── collapsible.tsx │ │ ├── label.tsx │ │ ├── textarea.tsx │ │ ├── input.tsx │ │ ├── separator.tsx │ │ ├── progress.tsx │ │ ├── toaster.tsx │ │ ├── sonner.tsx │ │ ├── checkbox.tsx │ │ ├── slider.tsx │ │ ├── switch.tsx │ │ ├── tooltip.tsx │ │ ├── badge.tsx │ │ ├── hover-card.tsx │ │ ├── popover.tsx │ │ ├── avatar.tsx │ │ ├── toggle.tsx │ │ ├── radio-group.tsx │ │ ├── alert.tsx │ │ ├── scroll-area.tsx │ │ ├── resizable.tsx │ │ ├── toggle-group.tsx │ │ ├── tabs.tsx │ │ ├── button.tsx │ │ ├── accordion.tsx │ │ ├── card.tsx │ │ ├── input-otp.tsx │ │ ├── calendar.tsx │ │ ├── breadcrumb.tsx │ │ ├── pagination.tsx │ │ ├── table.tsx │ │ ├── drawer.tsx │ │ ├── dialog.tsx │ │ ├── sheet.tsx │ │ ├── form.tsx │ │ ├── alert-dialog.tsx │ │ ├── toast.tsx │ │ ├── command.tsx │ │ ├── navigation-menu.tsx │ │ ├── select.tsx │ │ └── carousel.tsx │ ├── ServiceCard.tsx │ ├── TestimonialCard.tsx │ ├── ProjectCard.tsx │ ├── BlogCard.tsx │ ├── Footer.tsx │ ├── TestimonialsSection.tsx │ ├── BlogSection.tsx │ ├── PortfolioSection.tsx │ ├── ServicesSection.tsx │ ├── HeroSection.tsx │ ├── Navbar.tsx │ ├── AboutSection.tsx │ └── ContactSection.tsx ├── main.tsx ├── lib │ └── utils.ts ├── sanityClient.ts ├── hooks │ ├── use-mobile.tsx │ └── use-toast.ts ├── App.css ├── pages │ ├── NotFound.tsx │ ├── Index.tsx │ └── Portfolio.tsx ├── App.tsx └── index.css ├── netlify.toml ├── bun.lockb ├── backend ├── static │ └── .gitkeep ├── eslint.config.mjs ├── schemaTypes │ ├── index.ts │ ├── testimonials.ts │ ├── portfolio.ts │ └── blog.ts ├── sanity.cli.ts ├── sanity.config.ts ├── tsconfig.json ├── README.md ├── .gitignore └── package.json ├── postcss.config.js ├── tsconfig.json ├── components.json ├── tsconfig.node.json ├── vite.config.ts ├── tsconfig.app.json ├── .gitignore ├── .github └── workflows │ └── deploy.yml ├── eslint.config.js ├── LICENSE ├── README.md ├── index.html ├── package.json ├── vite.config.ts.timestamp-1742254671665-074b669b5ca11.mjs └── tailwind.config.ts /public/_redirects: -------------------------------------------------------------------------------- 1 | /* /index.html 200 -------------------------------------------------------------------------------- /src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | command = "npm run build" 3 | publish = "dist" -------------------------------------------------------------------------------- /bun.lockb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rohanmistry231/AI-WebStudio/main/bun.lockb -------------------------------------------------------------------------------- /public/hi.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rohanmistry231/AI-WebStudio/main/public/hi.gif -------------------------------------------------------------------------------- /public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rohanmistry231/AI-WebStudio/main/public/logo.png -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rohanmistry231/AI-WebStudio/main/public/favicon.ico -------------------------------------------------------------------------------- /public/profile.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rohanmistry231/AI-WebStudio/main/public/profile.jpg -------------------------------------------------------------------------------- /backend/static/.gitkeep: -------------------------------------------------------------------------------- 1 | Files placed here will be served by the Sanity server under the `/static`-prefix 2 | -------------------------------------------------------------------------------- /public/favicon-32x32.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rohanmistry231/AI-WebStudio/main/public/favicon-32x32.jpg -------------------------------------------------------------------------------- /public/favicon-64x64.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rohanmistry231/AI-WebStudio/main/public/favicon-64x64.jpg -------------------------------------------------------------------------------- /public/icon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rohanmistry231/AI-WebStudio/main/public/icon-192x192.png -------------------------------------------------------------------------------- /public/icon-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rohanmistry231/AI-WebStudio/main/public/icon-512x512.png -------------------------------------------------------------------------------- /backend/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import studio from '@sanity/eslint-config-studio' 2 | 3 | export default [...studio] 4 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /src/components/ui/use-toast.ts: -------------------------------------------------------------------------------- 1 | import { useToast, toast } from "@/hooks/use-toast"; 2 | 3 | export { useToast, toast }; 4 | -------------------------------------------------------------------------------- /src/main.tsx: -------------------------------------------------------------------------------- 1 | import { createRoot } from 'react-dom/client' 2 | import App from './App.tsx' 3 | import './index.css' 4 | 5 | createRoot(document.getElementById("root")!).render(); 6 | -------------------------------------------------------------------------------- /src/components/ui/aspect-ratio.tsx: -------------------------------------------------------------------------------- 1 | import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio" 2 | 3 | const AspectRatio = AspectRatioPrimitive.Root 4 | 5 | export { AspectRatio } 6 | -------------------------------------------------------------------------------- /src/lib/utils.ts: -------------------------------------------------------------------------------- 1 | import { clsx, type ClassValue } from "clsx" 2 | import { twMerge } from "tailwind-merge" 3 | 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)) 6 | } 7 | -------------------------------------------------------------------------------- /backend/schemaTypes/index.ts: -------------------------------------------------------------------------------- 1 | import blog from "./blog"; 2 | import testimonial from "./testimonials"; 3 | import portfolio from "./portfolio"; 4 | 5 | export const schemaTypes = [blog, testimonial, portfolio]; 6 | -------------------------------------------------------------------------------- /src/components/ui/skeleton.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from "@/lib/utils" 2 | 3 | function Skeleton({ 4 | className, 5 | ...props 6 | }: React.HTMLAttributes) { 7 | return ( 8 |
12 | ) 13 | } 14 | 15 | export { Skeleton } 16 | -------------------------------------------------------------------------------- /backend/sanity.cli.ts: -------------------------------------------------------------------------------- 1 | import {defineCliConfig} from 'sanity/cli' 2 | 3 | export default defineCliConfig({ 4 | api: { 5 | projectId: 'sjvie6s3', 6 | dataset: 'production' 7 | }, 8 | /** 9 | * Enable auto-updates for studios. 10 | * Learn more at https://www.sanity.io/docs/cli#auto-updates 11 | */ 12 | autoUpdates: true, 13 | }) 14 | -------------------------------------------------------------------------------- /src/components/ui/collapsible.tsx: -------------------------------------------------------------------------------- 1 | import * as CollapsiblePrimitive from "@radix-ui/react-collapsible" 2 | 3 | const Collapsible = CollapsiblePrimitive.Root 4 | 5 | const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger 6 | 7 | const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent 8 | 9 | export { Collapsible, CollapsibleTrigger, CollapsibleContent } 10 | -------------------------------------------------------------------------------- /src/sanityClient.ts: -------------------------------------------------------------------------------- 1 | import { createClient } from "@sanity/client"; 2 | 3 | const client = createClient({ 4 | projectId: "sjvie6s3", // Replace with your actual project ID 5 | dataset: "production", // Replace with your dataset name 6 | useCdn: true, // Set to false if you want fresh data on every request 7 | apiVersion: "2023-01-01", // Use the latest API version 8 | }); 9 | 10 | export default client; 11 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { "path": "./tsconfig.app.json" }, 5 | { "path": "./tsconfig.node.json" } 6 | ], 7 | "compilerOptions": { 8 | "baseUrl": ".", 9 | "paths": { 10 | "@/*": ["./src/*"] 11 | }, 12 | "noImplicitAny": false, 13 | "noUnusedParameters": false, 14 | "skipLibCheck": true, 15 | "allowJs": true, 16 | "noUnusedLocals": false, 17 | "strictNullChecks": false 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /backend/sanity.config.ts: -------------------------------------------------------------------------------- 1 | import {defineConfig} from 'sanity' 2 | import {structureTool} from 'sanity/structure' 3 | import {visionTool} from '@sanity/vision' 4 | import {schemaTypes} from './schemaTypes' 5 | 6 | export default defineConfig({ 7 | name: 'default', 8 | title: 'ai webstudio', 9 | 10 | projectId: 'sjvie6s3', 11 | dataset: 'production', 12 | 13 | plugins: [structureTool(), visionTool()], 14 | 15 | schema: { 16 | types: schemaTypes, 17 | }, 18 | }) 19 | -------------------------------------------------------------------------------- /backend/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2017", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "module": "Preserve", 10 | "moduleDetection": "force", 11 | "isolatedModules": true, 12 | "jsx": "preserve", 13 | "incremental": true 14 | }, 15 | "include": ["**/*.ts", "**/*.tsx"], 16 | "exclude": ["node_modules"] 17 | } 18 | -------------------------------------------------------------------------------- /components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "default", 4 | "rsc": false, 5 | "tsx": true, 6 | "tailwind": { 7 | "config": "tailwind.config.ts", 8 | "css": "src/index.css", 9 | "baseColor": "slate", 10 | "cssVariables": true, 11 | "prefix": "" 12 | }, 13 | "aliases": { 14 | "components": "@/components", 15 | "utils": "@/lib/utils", 16 | "ui": "@/components/ui", 17 | "lib": "@/lib", 18 | "hooks": "@/hooks" 19 | } 20 | } -------------------------------------------------------------------------------- /backend/README.md: -------------------------------------------------------------------------------- 1 | # Sanity Clean Content Studio 2 | 3 | Congratulations, you have now installed the Sanity Content Studio, an open-source real-time content editing environment connected to the Sanity backend. 4 | 5 | Now you can do the following things: 6 | 7 | - [Read “getting started” in the docs](https://www.sanity.io/docs/introduction/getting-started?utm_source=readme) 8 | - [Join the community Slack](https://slack.sanity.io/?utm_source=readme) 9 | - [Extend and build plugins](https://www.sanity.io/docs/content-studio/extending?utm_source=readme) 10 | -------------------------------------------------------------------------------- /backend/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # Dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # Compiled Sanity Studio 9 | /dist 10 | 11 | # Temporary Sanity runtime, generated by the CLI on every dev server start 12 | /.sanity 13 | 14 | # Logs 15 | /logs 16 | *.log 17 | 18 | # Coverage directory used by testing tools 19 | /coverage 20 | 21 | # Misc 22 | .DS_Store 23 | *.pem 24 | 25 | # Typescript 26 | *.tsbuildinfo 27 | 28 | # Dotenv and similar local-only files 29 | *.local 30 | -------------------------------------------------------------------------------- /tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2022", 4 | "lib": ["ES2023"], 5 | "module": "ESNext", 6 | "skipLibCheck": true, 7 | 8 | /* Bundler mode */ 9 | "moduleResolution": "bundler", 10 | "allowImportingTsExtensions": true, 11 | "isolatedModules": true, 12 | "moduleDetection": "force", 13 | "noEmit": true, 14 | 15 | /* Linting */ 16 | "strict": true, 17 | "noUnusedLocals": false, 18 | "noUnusedParameters": false, 19 | "noFallthroughCasesInSwitch": true 20 | }, 21 | "include": ["vite.config.ts"] 22 | } 23 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vite"; 2 | import react from "@vitejs/plugin-react-swc"; 3 | import path from "path"; 4 | import { componentTagger } from "lovable-tagger"; 5 | 6 | // https://vitejs.dev/config/ 7 | export default defineConfig(({ mode }) => ({ 8 | server: { 9 | host: "::", 10 | port: 8080, 11 | allowedHosts: ["820f-2409-40c1-10d2-533f-45-2873-542e-b958.ngrok-free.app"] 12 | }, 13 | plugins: [ 14 | react(), 15 | mode === 'development' && 16 | componentTagger(), 17 | ].filter(Boolean), 18 | resolve: { 19 | alias: { 20 | "@": path.resolve(__dirname, "./src"), 21 | }, 22 | }, 23 | })); 24 | -------------------------------------------------------------------------------- /src/hooks/use-mobile.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | const MOBILE_BREAKPOINT = 768 4 | 5 | export function useIsMobile() { 6 | const [isMobile, setIsMobile] = React.useState(undefined) 7 | 8 | React.useEffect(() => { 9 | const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`) 10 | const onChange = () => { 11 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT) 12 | } 13 | mql.addEventListener("change", onChange) 14 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT) 15 | return () => mql.removeEventListener("change", onChange) 16 | }, []) 17 | 18 | return !!isMobile 19 | } 20 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "AI WebStudio", 3 | "start_url": "/", 4 | "display": "standalone", 5 | "background_color": "#ffffff", 6 | "theme_color": "#000000", 7 | "description": "AI WebStudio - AI-powered and customized website development", 8 | "icons": [ 9 | { 10 | "src": "icon-192x192.png", 11 | "sizes": "192x192", 12 | "type": "image/png" 13 | }, 14 | { 15 | "src": "icon-512x512.png", 16 | "sizes": "512x512", 17 | "type": "image/png" 18 | }, 19 | { 20 | "src": "favicon-64x64.png", 21 | "sizes": "64x64", 22 | "type": "image/png" 23 | }, 24 | { 25 | "src": "favicon-32x32.png", 26 | "sizes": "32x32", 27 | "type": "image/png" 28 | } 29 | ] 30 | } -------------------------------------------------------------------------------- /tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "isolatedModules": true, 13 | "moduleDetection": "force", 14 | "noEmit": true, 15 | "jsx": "react-jsx", 16 | 17 | /* Linting */ 18 | "strict": false, 19 | "noUnusedLocals": false, 20 | "noUnusedParameters": false, 21 | "noImplicitAny": false, 22 | "noFallthroughCasesInSwitch": false, 23 | 24 | "baseUrl": ".", 25 | "paths": { 26 | "@/*": ["./src/*"] 27 | } 28 | }, 29 | "include": ["src"] 30 | } 31 | -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | #root { 2 | max-width: 1280px; 3 | margin: 0 auto; 4 | padding: 2rem; 5 | text-align: center; 6 | } 7 | 8 | .logo { 9 | height: 6em; 10 | padding: 1.5em; 11 | will-change: filter; 12 | transition: filter 300ms; 13 | } 14 | .logo:hover { 15 | filter: drop-shadow(0 0 2em #646cffaa); 16 | } 17 | .logo.react:hover { 18 | filter: drop-shadow(0 0 2em #61dafbaa); 19 | } 20 | 21 | @keyframes logo-spin { 22 | from { 23 | transform: rotate(0deg); 24 | } 25 | to { 26 | transform: rotate(360deg); 27 | } 28 | } 29 | 30 | @media (prefers-reduced-motion: no-preference) { 31 | a:nth-of-type(2) .logo { 32 | animation: logo-spin infinite 20s linear; 33 | } 34 | } 35 | 36 | .card { 37 | padding: 2em; 38 | } 39 | 40 | .read-the-docs { 41 | color: #888; 42 | } 43 | 44 | -------------------------------------------------------------------------------- /src/components/ui/label.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import * as LabelPrimitive from "@radix-ui/react-label" 3 | import { cva, type VariantProps } from "class-variance-authority" 4 | 5 | import { cn } from "@/lib/utils" 6 | 7 | const labelVariants = cva( 8 | "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" 9 | ) 10 | 11 | const Label = React.forwardRef< 12 | React.ElementRef, 13 | React.ComponentPropsWithoutRef & 14 | VariantProps 15 | >(({ className, ...props }, ref) => ( 16 | 21 | )) 22 | Label.displayName = LabelPrimitive.Root.displayName 23 | 24 | export { Label } 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | 25 | # Logs 26 | logs 27 | *.log 28 | npm-debug.log* 29 | yarn-debug.log* 30 | yarn-error.log* 31 | pnpm-debug.log* 32 | lerna-debug.log* 33 | 34 | node_modules 35 | dist 36 | dist-ssr 37 | *.local 38 | 39 | # Editor directories and files 40 | .vscode/* 41 | !.vscode/extensions.json 42 | .idea 43 | .DS_Store 44 | *.suo 45 | *.ntvs* 46 | *.njsproj 47 | *.sln 48 | *.sw? 49 | .env -------------------------------------------------------------------------------- /src/pages/NotFound.tsx: -------------------------------------------------------------------------------- 1 | import { useLocation } from "react-router-dom"; 2 | import { useEffect } from "react"; 3 | 4 | const NotFound = () => { 5 | const location = useLocation(); 6 | 7 | useEffect(() => { 8 | console.error( 9 | "404 Error: User attempted to access non-existent route:", 10 | location.pathname 11 | ); 12 | }, [location.pathname]); 13 | 14 | return ( 15 |
16 |
17 |

404

18 |

Oops! Page not found

19 | 20 | Return to Home 21 | 22 |
23 |
24 | ); 25 | }; 26 | 27 | export default NotFound; 28 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: Deploy to Netlify 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | build-and-deploy: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - name: Checkout code 14 | uses: actions/checkout@v3 15 | 16 | - name: Setup Node.js 17 | uses: actions/setup-node@v3 18 | with: 19 | node-version: '18' 20 | 21 | - name: Install dependencies 22 | run: npm install 23 | 24 | - name: Build project 25 | run: npm run build 26 | 27 | - name: Deploy to Netlify 28 | uses: netlify/actions/cli@master 29 | with: 30 | args: deploy --dir=build --prod 31 | env: 32 | NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} 33 | NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }} -------------------------------------------------------------------------------- /src/components/ui/textarea.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | import { cn } from "@/lib/utils" 4 | 5 | export interface TextareaProps 6 | extends React.TextareaHTMLAttributes {} 7 | 8 | const Textarea = React.forwardRef( 9 | ({ className, ...props }, ref) => { 10 | return ( 11 |