Add ContactForm component and utility functions; update Navbar styles
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"$schema": "https://ui.shadcn.com/schema.json",
|
||||
"style": "new-york",
|
||||
"rsc": true,
|
||||
"tsx": false,
|
||||
"tailwind": {
|
||||
"config": "",
|
||||
"css": "src/app/globals.css",
|
||||
"baseColor": "slate",
|
||||
"cssVariables": true,
|
||||
"prefix": ""
|
||||
},
|
||||
"aliases": {
|
||||
"components": "@/components",
|
||||
"utils": "@/lib/utils",
|
||||
"ui": "@/components/ui",
|
||||
"lib": "@/lib",
|
||||
"hooks": "@/hooks"
|
||||
},
|
||||
"iconLibrary": "lucide"
|
||||
}
|
||||
Generated
+325
-1
@@ -10,13 +10,19 @@
|
||||
"dependencies": {
|
||||
"@next/env": "15.2.4",
|
||||
"@next/third-parties": "15.2.4",
|
||||
"@radix-ui/react-accordion": "^1.2.3",
|
||||
"@vercel/analytics": "^1.4.1",
|
||||
"@vercel/speed-insights": "^1.1.0",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"lucide-react": "^0.487.0",
|
||||
"motion": "^11.16.0",
|
||||
"next": "15.2.4",
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0",
|
||||
"sharp": "^0.33.5"
|
||||
"sharp": "^0.33.5",
|
||||
"tailwind-merge": "^3.1.0",
|
||||
"tw-animate-css": "^1.2.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/postcss": "^4.1.1",
|
||||
@@ -752,6 +758,275 @@
|
||||
"node": ">=12.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/primitive": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.1.tgz",
|
||||
"integrity": "sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@radix-ui/react-accordion": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.3.tgz",
|
||||
"integrity": "sha512-RIQ15mrcvqIkDARJeERSuXSry2N8uYnxkdDetpfmalT/+0ntOXLkFOsh9iwlAsCv+qcmhZjbdJogIm6WBa6c4A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/primitive": "1.1.1",
|
||||
"@radix-ui/react-collapsible": "1.1.3",
|
||||
"@radix-ui/react-collection": "1.1.2",
|
||||
"@radix-ui/react-compose-refs": "1.1.1",
|
||||
"@radix-ui/react-context": "1.1.1",
|
||||
"@radix-ui/react-direction": "1.1.0",
|
||||
"@radix-ui/react-id": "1.1.0",
|
||||
"@radix-ui/react-primitive": "2.0.2",
|
||||
"@radix-ui/react-use-controllable-state": "1.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-collapsible": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.3.tgz",
|
||||
"integrity": "sha512-jFSerheto1X03MUC0g6R7LedNW9EEGWdg9W1+MlpkMLwGkgkbUXLPBH/KIuWKXUoeYRVY11llqbTBDzuLg7qrw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/primitive": "1.1.1",
|
||||
"@radix-ui/react-compose-refs": "1.1.1",
|
||||
"@radix-ui/react-context": "1.1.1",
|
||||
"@radix-ui/react-id": "1.1.0",
|
||||
"@radix-ui/react-presence": "1.1.2",
|
||||
"@radix-ui/react-primitive": "2.0.2",
|
||||
"@radix-ui/react-use-controllable-state": "1.1.0",
|
||||
"@radix-ui/react-use-layout-effect": "1.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-collection": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.2.tgz",
|
||||
"integrity": "sha512-9z54IEKRxIa9VityapoEYMuByaG42iSy1ZXlY2KcuLSEtq8x4987/N6m15ppoMffgZX72gER2uHe1D9Y6Unlcw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-compose-refs": "1.1.1",
|
||||
"@radix-ui/react-context": "1.1.1",
|
||||
"@radix-ui/react-primitive": "2.0.2",
|
||||
"@radix-ui/react-slot": "1.1.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-compose-refs": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.1.tgz",
|
||||
"integrity": "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-context": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz",
|
||||
"integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-direction": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.0.tgz",
|
||||
"integrity": "sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-id": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz",
|
||||
"integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-use-layout-effect": "1.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-presence": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.2.tgz",
|
||||
"integrity": "sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-compose-refs": "1.1.1",
|
||||
"@radix-ui/react-use-layout-effect": "1.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-primitive": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.2.tgz",
|
||||
"integrity": "sha512-Ec/0d38EIuvDF+GZjcMU/Ze6MxntVJYO/fRlCPhCaVUyPY9WTalHJw54tp9sXeJo3tlShWpy41vQRgLRGOuz+w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-slot": "1.1.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-slot": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.2.tgz",
|
||||
"integrity": "sha512-YAKxaiGsSQJ38VzKH86/BPRC4rh+b1Jpa+JneA5LRE7skmLPNAyeG8kPJj/oo4STLvlrs8vkf/iYyc3A5stYCQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-compose-refs": "1.1.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-use-callback-ref": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz",
|
||||
"integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-use-controllable-state": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz",
|
||||
"integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-use-callback-ref": "1.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-use-layout-effect": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz",
|
||||
"integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@rtsao/scc": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz",
|
||||
@@ -2021,12 +2296,33 @@
|
||||
"url": "https://github.com/chalk/chalk?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/class-variance-authority": {
|
||||
"version": "0.7.1",
|
||||
"resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz",
|
||||
"integrity": "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"clsx": "^2.1.1"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://polar.sh/cva"
|
||||
}
|
||||
},
|
||||
"node_modules/client-only": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
|
||||
"integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/clsx": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
|
||||
"integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/color": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
|
||||
@@ -4277,6 +4573,15 @@
|
||||
"loose-envify": "cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/lucide-react": {
|
||||
"version": "0.487.0",
|
||||
"resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.487.0.tgz",
|
||||
"integrity": "sha512-aKqhOQ+YmFnwq8dWgGjOuLc8V1R9/c/yOd+zDY4+ohsR2Jo05lSGc3WsstYPIzcTpeosN7LoCkLReUUITvaIvw==",
|
||||
"license": "ISC",
|
||||
"peerDependencies": {
|
||||
"react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/math-intrinsics": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
||||
@@ -5507,6 +5812,16 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/tailwind-merge": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.1.0.tgz",
|
||||
"integrity": "sha512-aV27Oj8B7U/tAOMhJsSGdWqelfmudnGMdXIlMnk1JfsjwSjts6o8HyfN7SFH3EztzH4YH8kk6GbLTHzITJO39Q==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/dcastil"
|
||||
}
|
||||
},
|
||||
"node_modules/tailwindcss": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.1.tgz",
|
||||
@@ -5627,6 +5942,15 @@
|
||||
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
||||
"license": "0BSD"
|
||||
},
|
||||
"node_modules/tw-animate-css": {
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/tw-animate-css/-/tw-animate-css-1.2.5.tgz",
|
||||
"integrity": "sha512-ABzjfgVo+fDbhRREGL4KQZUqqdPgvc5zVrLyeW9/6mVqvaDepXc7EvedA+pYmMnIOsUAQMwcWzNvom26J2qYvQ==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/Wombosvideo"
|
||||
}
|
||||
},
|
||||
"node_modules/type-check": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
|
||||
|
||||
+7
-1
@@ -11,13 +11,19 @@
|
||||
"dependencies": {
|
||||
"@next/env": "15.2.4",
|
||||
"@next/third-parties": "15.2.4",
|
||||
"@radix-ui/react-accordion": "^1.2.3",
|
||||
"@vercel/analytics": "^1.4.1",
|
||||
"@vercel/speed-insights": "^1.1.0",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"lucide-react": "^0.487.0",
|
||||
"motion": "^11.16.0",
|
||||
"next": "15.2.4",
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0",
|
||||
"sharp": "^0.33.5"
|
||||
"sharp": "^0.33.5",
|
||||
"tailwind-merge": "^3.1.0",
|
||||
"tw-animate-css": "^1.2.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/postcss": "^4.1.1",
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
import styles from "./ContactForm.module.css";
|
||||
|
||||
export default function ContactForm() {
|
||||
return (
|
||||
<div>
|
||||
<h2 className="text-3xl font-bold mb-4">Contact Us</h2>
|
||||
<div className={styles.contactDetails}>
|
||||
<h3 className="text-lg font-bold hover:underline">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 20 20"
|
||||
fill="currentColor"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M2 3.5A1.5 1.5 0 0 1 3.5 2h1.148a1.5 1.5 0 0 1 1.465 1.175l.716 3.223a1.5 1.5 0 0 1-1.052 1.767l-.933.267c-.41.117-.643.555-.48.95a11.542 11.542 0 0 0 6.254 6.254c.395.163.833-.07.95-.48l.267-.933a1.5 1.5 0 0 1 1.767-1.052l3.223.716A1.5 1.5 0 0 1 18 15.352V16.5a1.5 1.5 0 0 1-1.5 1.5H15c-1.149 0-2.263-.15-3.326-.43A13.022 13.022 0 0 1 2.43 8.326 13.019 13.019 0 0 1 2 5V3.5Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
<a href="tel:+640211077483">021 107 7483</a>
|
||||
</h3>
|
||||
<h3 className="text-lg font-bold hover:underline">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 20 20"
|
||||
fill="currentColor"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M5.404 14.596A6.5 6.5 0 1 1 16.5 10a1.25 1.25 0 0 1-2.5 0 4 4 0 1 0-.571 2.06A2.75 2.75 0 0 0 18 10a8 8 0 1 0-2.343 5.657.75.75 0 0 0-1.06-1.06 6.5 6.5 0 0 1-9.193 0ZM10 7.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
<a href="mailto:[email protected]">
|
||||
info@teatatucomputers.com
|
||||
</a>
|
||||
</h3>
|
||||
</div>
|
||||
<form
|
||||
action="https://form.taxi/s/es9ddva1"
|
||||
method="POST"
|
||||
className={styles.form}
|
||||
>
|
||||
<label htmlFor="Name">Name*</label>
|
||||
<input type="text" name="Name" required />
|
||||
|
||||
<label htmlFor="Phone">Phone Number </label>
|
||||
<input type="tel" name="Phone" />
|
||||
|
||||
<label htmlFor="Email">Email*</label>
|
||||
<input type="email" name="Email" required />
|
||||
|
||||
<label htmlFor="firstname">Message*</label>
|
||||
<textarea name="Message"></textarea>
|
||||
|
||||
<p className={styles.sm}>* required</p>
|
||||
|
||||
<input
|
||||
type="submit"
|
||||
value="Submit"
|
||||
required
|
||||
className="text-white bg-sky-800 hover:bg-sky-700 transition"
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,7 +1,3 @@
|
||||
.form {
|
||||
margin-bottom: 35em;
|
||||
}
|
||||
|
||||
.form input[type="text"],
|
||||
.form input[type="email"],
|
||||
.form input[type="tel"],
|
||||
@@ -26,8 +22,8 @@
|
||||
}
|
||||
|
||||
.sm {
|
||||
font-size: 0.75em;
|
||||
font-style: italic;
|
||||
font-size: 0.75em;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.contactDetails {
|
||||
@@ -42,4 +38,4 @@
|
||||
|
||||
.contactDetails h3 a {
|
||||
color: black;
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import logo from "../assets/logo.svg";
|
||||
import menu from "../assets/menu.svg";
|
||||
import close from "../assets/close.svg";
|
||||
import { usePathname } from "next/navigation";
|
||||
import { ChevronDownIcon } from "lucide-react";
|
||||
// import { motion } from "motion/react"
|
||||
|
||||
export default function Navbar() {
|
||||
@@ -82,33 +83,87 @@ export default function Navbar() {
|
||||
${styles.dropdown}
|
||||
${isDropdownActive && !isActive ? styles.dropdownActive : ""}
|
||||
`}
|
||||
onMouseEnter={() => setDropdownActive(true)}
|
||||
onMouseLeave={() => setDropdownActive(false)}
|
||||
>
|
||||
<a
|
||||
className={`${styles.dropdownTitle}
|
||||
${pathname === "/services" ? styles.active : ""}`}
|
||||
onClick={handleDropdownToggle}
|
||||
<div
|
||||
data-state={isDropdownActive ? "open" : "close"}
|
||||
className="flex items-center justify-center gap-1 [&[data-state=open]>svg]:rotate-180"
|
||||
>
|
||||
Services
|
||||
</a>
|
||||
<a
|
||||
className={`${styles.dropdownTitle}
|
||||
${pathname === "/services" ? styles.active : ""}`}
|
||||
onClick={handleDropdownToggle}
|
||||
>
|
||||
Services
|
||||
</a>
|
||||
<ChevronDownIcon className="text-muted-foreground pointer-events-none size-4 shrink-0 translate-y-0.5 transition-transform duration-200" />
|
||||
</div>
|
||||
<ul className={styles.dropdownMenu}>
|
||||
<li>
|
||||
<Link href="/services/computer-repair" className={`link ${pathname === "/services/computer-repair" ? styles.active : ""}`}>Computer & Laptop Repairs</Link>
|
||||
<Link
|
||||
href="/services/computer-repair"
|
||||
className={`link ${
|
||||
pathname === "/services/computer-repair"
|
||||
? styles.active
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
Computer & Laptop Repairs
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link href="/services/computer-upgrades" className={`link ${pathname === "/services/computer-upgrades" ? styles.active : ""}`}>Computer Upgrades & Speedup</Link>
|
||||
<Link
|
||||
href="/services/computer-upgrades"
|
||||
className={`link ${
|
||||
pathname === "/services/computer-upgrades"
|
||||
? styles.active
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
Computer Upgrades & Speedup
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link href="/services/it-support" className={`link ${pathname === "/services/it-support" ? styles.active : ""}`}>IT Support</Link>
|
||||
<Link
|
||||
href="/services/it-support"
|
||||
className={`link ${
|
||||
pathname === "/services/it-support" ? styles.active : ""
|
||||
}`}
|
||||
>
|
||||
IT Support
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link href="/services/web-design" className={`link ${pathname === "/services/web-design" ? styles.active : ""}`}>Web Design</Link>
|
||||
<Link
|
||||
href="/services/web-design"
|
||||
className={`link ${
|
||||
pathname === "/services/web-design" ? styles.active : ""
|
||||
}`}
|
||||
>
|
||||
Web Design
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link href="/services/virus-removal" className={`link ${pathname === "/services/virus-removal" ? styles.active : ""}`}>Virus Removal</Link>
|
||||
<Link
|
||||
href="/services/virus-removal"
|
||||
className={`link ${
|
||||
pathname === "/services/virus-removal" ? styles.active : ""
|
||||
}`}
|
||||
>
|
||||
Virus Removal
|
||||
</Link>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li className="bg-sky-900 text-white">
|
||||
<li>
|
||||
<Link
|
||||
href="/#faq"
|
||||
>
|
||||
FAQ
|
||||
</Link>
|
||||
</li>
|
||||
<li className="bg-sky-900 text-white lg:ml-4">
|
||||
<Link
|
||||
href="/contact"
|
||||
className={`link ${pathname === "/contact" ? styles.active : ""}`}
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
border-radius: 0;
|
||||
|
||||
position: absolute;
|
||||
top: -10em;
|
||||
top: -14em;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: -2;
|
||||
|
||||
+3
-62
@@ -1,71 +1,12 @@
|
||||
import styles from "./page.module.css";
|
||||
import HeaderSm from "../components/HeaderSm";
|
||||
import ContactForm from "../components/ContactForm";
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<div>
|
||||
<HeaderSm text="Contact" />
|
||||
<section className="container mx-auto">
|
||||
<p className="mb-4">
|
||||
Contact us about anything related to our company or services.
|
||||
<br />
|
||||
We'll do our best to get back to you as soon as possible.
|
||||
</p>
|
||||
<div className={styles.contactDetails}>
|
||||
<h3 className="text-lg font-bold hover:underline">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 20 20"
|
||||
fill="currentColor"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M2 3.5A1.5 1.5 0 0 1 3.5 2h1.148a1.5 1.5 0 0 1 1.465 1.175l.716 3.223a1.5 1.5 0 0 1-1.052 1.767l-.933.267c-.41.117-.643.555-.48.95a11.542 11.542 0 0 0 6.254 6.254c.395.163.833-.07.95-.48l.267-.933a1.5 1.5 0 0 1 1.767-1.052l3.223.716A1.5 1.5 0 0 1 18 15.352V16.5a1.5 1.5 0 0 1-1.5 1.5H15c-1.149 0-2.263-.15-3.326-.43A13.022 13.022 0 0 1 2.43 8.326 13.019 13.019 0 0 1 2 5V3.5Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
<a href="tel:+640211077483">021 107 7483</a>
|
||||
</h3>
|
||||
<h3 className="text-lg font-bold hover:underline">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 20 20"
|
||||
fill="currentColor"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M5.404 14.596A6.5 6.5 0 1 1 16.5 10a1.25 1.25 0 0 1-2.5 0 4 4 0 1 0-.571 2.06A2.75 2.75 0 0 0 18 10a8 8 0 1 0-2.343 5.657.75.75 0 0 0-1.06-1.06 6.5 6.5 0 0 1-9.193 0ZM10 7.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
<a href="mailto:[email protected]">
|
||||
info@teatatucomputers.com
|
||||
</a>
|
||||
</h3>
|
||||
</div>
|
||||
<form
|
||||
action="https://form.taxi/s/es9ddva1"
|
||||
method="POST"
|
||||
className={styles.form}
|
||||
>
|
||||
<label htmlFor="Name">Name*</label>
|
||||
<input type="text" name="Name" required />
|
||||
|
||||
<label htmlFor="Phone">Phone Number </label>
|
||||
<input type="tel" name="Phone" />
|
||||
|
||||
<label htmlFor="Email">Email*</label>
|
||||
<input type="email" name="Email" required />
|
||||
|
||||
<label htmlFor="firstname">Message*</label>
|
||||
<textarea name="Message"></textarea>
|
||||
|
||||
<p className={styles.sm}>* required</p>
|
||||
|
||||
<input type="submit" value="Submit" required className="text-white bg-sky-800 hover:bg-sky-700 transition" />
|
||||
</form>
|
||||
<section className="container mx-auto mb-64">
|
||||
<ContactForm />
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
@import 'tailwindcss';
|
||||
@import "tw-animate-css";
|
||||
/*
|
||||
---break---
|
||||
*/
|
||||
@custom-variant dark (&:is(.dark *));
|
||||
|
||||
@utility container {
|
||||
padding-inline: 1rem;
|
||||
@@ -20,4 +25,128 @@
|
||||
::file-selector-button {
|
||||
border-color: var(--color-gray-200, currentColor);
|
||||
}
|
||||
}
|
||||
/*
|
||||
---break---
|
||||
*/
|
||||
:root {
|
||||
--radius: 0.625rem;
|
||||
--background: oklch(1 0 0);
|
||||
--foreground: oklch(0.129 0.042 264.695);
|
||||
--card: oklch(1 0 0);
|
||||
--card-foreground: oklch(0.129 0.042 264.695);
|
||||
--popover: oklch(1 0 0);
|
||||
--popover-foreground: oklch(0.129 0.042 264.695);
|
||||
--primary: oklch(0.208 0.042 265.755);
|
||||
--primary-foreground: oklch(0.984 0.003 247.858);
|
||||
--secondary: oklch(0.968 0.007 247.896);
|
||||
--secondary-foreground: oklch(0.208 0.042 265.755);
|
||||
--muted: oklch(0.968 0.007 247.896);
|
||||
--muted-foreground: oklch(0.554 0.046 257.417);
|
||||
--accent: oklch(0.968 0.007 247.896);
|
||||
--accent-foreground: oklch(0.208 0.042 265.755);
|
||||
--destructive: oklch(0.577 0.245 27.325);
|
||||
--border: oklch(0.929 0.013 255.508);
|
||||
--input: oklch(0.929 0.013 255.508);
|
||||
--ring: oklch(0.704 0.04 256.788);
|
||||
--chart-1: oklch(0.646 0.222 41.116);
|
||||
--chart-2: oklch(0.6 0.118 184.704);
|
||||
--chart-3: oklch(0.398 0.07 227.392);
|
||||
--chart-4: oklch(0.828 0.189 84.429);
|
||||
--chart-5: oklch(0.769 0.188 70.08);
|
||||
--sidebar: oklch(0.984 0.003 247.858);
|
||||
--sidebar-foreground: oklch(0.129 0.042 264.695);
|
||||
--sidebar-primary: oklch(0.208 0.042 265.755);
|
||||
--sidebar-primary-foreground: oklch(0.984 0.003 247.858);
|
||||
--sidebar-accent: oklch(0.968 0.007 247.896);
|
||||
--sidebar-accent-foreground: oklch(0.208 0.042 265.755);
|
||||
--sidebar-border: oklch(0.929 0.013 255.508);
|
||||
--sidebar-ring: oklch(0.704 0.04 256.788);
|
||||
}
|
||||
/*
|
||||
---break---
|
||||
*/
|
||||
.dark {
|
||||
--background: oklch(0.129 0.042 264.695);
|
||||
--foreground: oklch(0.984 0.003 247.858);
|
||||
--card: oklch(0.208 0.042 265.755);
|
||||
--card-foreground: oklch(0.984 0.003 247.858);
|
||||
--popover: oklch(0.208 0.042 265.755);
|
||||
--popover-foreground: oklch(0.984 0.003 247.858);
|
||||
--primary: oklch(0.929 0.013 255.508);
|
||||
--primary-foreground: oklch(0.208 0.042 265.755);
|
||||
--secondary: oklch(0.279 0.041 260.031);
|
||||
--secondary-foreground: oklch(0.984 0.003 247.858);
|
||||
--muted: oklch(0.279 0.041 260.031);
|
||||
--muted-foreground: oklch(0.704 0.04 256.788);
|
||||
--accent: oklch(0.279 0.041 260.031);
|
||||
--accent-foreground: oklch(0.984 0.003 247.858);
|
||||
--destructive: oklch(0.704 0.191 22.216);
|
||||
--border: oklch(1 0 0 / 10%);
|
||||
--input: oklch(1 0 0 / 15%);
|
||||
--ring: oklch(0.551 0.027 264.364);
|
||||
--chart-1: oklch(0.488 0.243 264.376);
|
||||
--chart-2: oklch(0.696 0.17 162.48);
|
||||
--chart-3: oklch(0.769 0.188 70.08);
|
||||
--chart-4: oklch(0.627 0.265 303.9);
|
||||
--chart-5: oklch(0.645 0.246 16.439);
|
||||
--sidebar: oklch(0.208 0.042 265.755);
|
||||
--sidebar-foreground: oklch(0.984 0.003 247.858);
|
||||
--sidebar-primary: oklch(0.488 0.243 264.376);
|
||||
--sidebar-primary-foreground: oklch(0.984 0.003 247.858);
|
||||
--sidebar-accent: oklch(0.279 0.041 260.031);
|
||||
--sidebar-accent-foreground: oklch(0.984 0.003 247.858);
|
||||
--sidebar-border: oklch(1 0 0 / 10%);
|
||||
--sidebar-ring: oklch(0.551 0.027 264.364);
|
||||
}
|
||||
/*
|
||||
---break---
|
||||
*/
|
||||
@theme inline {
|
||||
--radius-sm: calc(var(--radius) - 4px);
|
||||
--radius-md: calc(var(--radius) - 2px);
|
||||
--radius-lg: var(--radius);
|
||||
--radius-xl: calc(var(--radius) + 4px);
|
||||
--color-background: var(--background);
|
||||
--color-foreground: var(--foreground);
|
||||
--color-card: var(--card);
|
||||
--color-card-foreground: var(--card-foreground);
|
||||
--color-popover: var(--popover);
|
||||
--color-popover-foreground: var(--popover-foreground);
|
||||
--color-primary: var(--primary);
|
||||
--color-primary-foreground: var(--primary-foreground);
|
||||
--color-secondary: var(--secondary);
|
||||
--color-secondary-foreground: var(--secondary-foreground);
|
||||
--color-muted: var(--muted);
|
||||
--color-muted-foreground: var(--muted-foreground);
|
||||
--color-accent: var(--accent);
|
||||
--color-accent-foreground: var(--accent-foreground);
|
||||
--color-destructive: var(--destructive);
|
||||
--color-border: var(--border);
|
||||
--color-input: var(--input);
|
||||
--color-ring: var(--ring);
|
||||
--color-chart-1: var(--chart-1);
|
||||
--color-chart-2: var(--chart-2);
|
||||
--color-chart-3: var(--chart-3);
|
||||
--color-chart-4: var(--chart-4);
|
||||
--color-chart-5: var(--chart-5);
|
||||
--color-sidebar: var(--sidebar);
|
||||
--color-sidebar-foreground: var(--sidebar-foreground);
|
||||
--color-sidebar-primary: var(--sidebar-primary);
|
||||
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
||||
--color-sidebar-accent: var(--sidebar-accent);
|
||||
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
||||
--color-sidebar-border: var(--sidebar-border);
|
||||
--color-sidebar-ring: var(--sidebar-ring);
|
||||
}
|
||||
/*
|
||||
---break---
|
||||
*/
|
||||
@layer base {
|
||||
* {
|
||||
@apply border-border outline-ring/50;
|
||||
}
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
}
|
||||
}
|
||||
+179
-4
@@ -4,6 +4,13 @@ import bgimage from "./assets/header-bg.jpg";
|
||||
import Button from "./components/Button";
|
||||
import Link from "next/link";
|
||||
import { GoogleMapsEmbed } from "@next/third-parties/google";
|
||||
import ContactForm from "./components/ContactForm";
|
||||
import {
|
||||
Accordion,
|
||||
AccordionContent,
|
||||
AccordionItem,
|
||||
AccordionTrigger,
|
||||
} from "@/components/ui/accordion";
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
@@ -61,7 +68,7 @@ export default function Home() {
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="container mx-auto mb-16">
|
||||
<section className="container mx-auto mb-32">
|
||||
<h1 className="text-center text-3xl font-bold mb-4">
|
||||
Services we Offer
|
||||
</h1>
|
||||
@@ -163,17 +170,185 @@ export default function Home() {
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section className="container mx-auto">
|
||||
<div className={styles.map}>
|
||||
<section className="container mx-auto flex flex-col gap-8 lg:flex-row mb-32">
|
||||
<ContactForm />
|
||||
<div className="w-full">
|
||||
<GoogleMapsEmbed
|
||||
apiKey="AIzaSyDbgQY55TQY5CefsCUwKbc8RfoOUe8U5gY"
|
||||
height="500px"
|
||||
width="100%"
|
||||
height="600px"
|
||||
mode="place"
|
||||
q="place_id:ChIJz0ZoDYhADW0R0TDgWoWMq0M"
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
<section className="container mx-auto mb-16 max-w-3xl mb-32" id="faq">
|
||||
<h1 className="text-center text-3xl font-bold mb-8">
|
||||
Frequently Asked Questions
|
||||
</h1>
|
||||
<h3 className="text-lg font-bold text-slate-900">
|
||||
Computer Repair and IT Support
|
||||
</h3>
|
||||
<Accordion className="mb-8">
|
||||
<AccordionItem value="item-1">
|
||||
<AccordionTrigger>
|
||||
What types of devices do you repair?
|
||||
</AccordionTrigger>
|
||||
<AccordionContent>
|
||||
We repair desktops, laptops, chromebooks and PCs. We also handle
|
||||
custom-built systems and some tablets, depending on the issue.
|
||||
Currently we do not repair Apple devices.
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
<AccordionItem value="item-2">
|
||||
<AccordionTrigger>
|
||||
What kinds of issues can you fix?
|
||||
</AccordionTrigger>
|
||||
<AccordionContent>
|
||||
We handle a wide range of problems, including (but not limited
|
||||
to):
|
||||
<ul className="list-disc pl-6 my-2">
|
||||
<li>
|
||||
Software issues (e.g. Windows errors, slow performance)
|
||||
</li>
|
||||
<li>Virus removal and protection</li>
|
||||
<li>Data recovery and backup solutions</li>
|
||||
<li>Network setup and troubleshooting</li>
|
||||
<li>Hardware upgrades (e.g. RAM, SSD, graphics card)</li>
|
||||
<li>Custom PC builds</li>
|
||||
<li>Web development and design</li>
|
||||
<li>Remote support for software issues</li>
|
||||
<li>General IT support and consulting</li>
|
||||
<li>Printer setup and troubleshooting</li>
|
||||
<li>Software installation and configuration</li>
|
||||
<li>Operating system installation and upgrades</li>
|
||||
<li>Data migration from old devices to new ones</li>
|
||||
</ul>
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
<AccordionItem value="item-3">
|
||||
<AccordionTrigger>
|
||||
Do I need an appointment, or can I just walk in?
|
||||
</AccordionTrigger>
|
||||
<AccordionContent>
|
||||
Currently we are operating by appointment only. Please contact
|
||||
us to schedule a time that works for you. We can also arrange
|
||||
remote support for certain issues.
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
<AccordionItem value="item-4">
|
||||
<AccordionTrigger>
|
||||
How long will the repair take?
|
||||
</AccordionTrigger>
|
||||
<AccordionContent>
|
||||
Most basic repairs are completed within 24-48 hours. Some issues
|
||||
may take longer, depending on parts availability and complexity.
|
||||
We’ll give you an estimated turnaround time when we diagnose the
|
||||
problem. Most parts take about a week to arrive.
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
</Accordion>
|
||||
|
||||
<h3 className="text-lg font-bold text-slate-900">
|
||||
Web Design and Development
|
||||
</h3>
|
||||
<Accordion>
|
||||
<AccordionItem value="item-1">
|
||||
<AccordionTrigger>
|
||||
What platforms do you build websites with?
|
||||
</AccordionTrigger>
|
||||
<AccordionContent>
|
||||
We specialize in modern web development using WordPress for
|
||||
content-driven sites and React/Next.js for high-performance,
|
||||
custom web applications. We also offer support for almost any
|
||||
website builder, whether it's Wix, Oddo, Squarespace, or
|
||||
anything else. Whether you need a blog, business site,
|
||||
portfolio, or a fully custom web app—we've got you covered.
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
|
||||
<AccordionItem value="item-2">
|
||||
<AccordionTrigger>
|
||||
How do I choose between WordPress and React/Next.js?
|
||||
</AccordionTrigger>
|
||||
<AccordionContent>
|
||||
It depends on your needs:
|
||||
<ul className="list-disc pl-6 my-2">
|
||||
<li>
|
||||
<strong>WordPress</strong> is best for content-heavy
|
||||
websites like blogs, portfolios, and marketing sites.
|
||||
</li>
|
||||
<li>
|
||||
<strong>React/Next.js</strong> is ideal for fast, scalable,
|
||||
custom web applications or interactive user interfaces.
|
||||
</li>
|
||||
</ul>
|
||||
We’ll help you decide what works best based on your goals and
|
||||
budget.
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
<AccordionItem value="item-3">
|
||||
<AccordionTrigger>
|
||||
Do you design the website too, or just build it?
|
||||
</AccordionTrigger>
|
||||
<AccordionContent>
|
||||
We do both! We offer full-service web design and development.
|
||||
This includes UX/UI design, branding, responsive layouts, and
|
||||
mobile-first design—all tailored to your needs.
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
<AccordionItem value="item-4">
|
||||
<AccordionTrigger>
|
||||
Can you redesign or improve my existing site?
|
||||
</AccordionTrigger>
|
||||
<AccordionContent>
|
||||
Absolutely. We can modernize your design, improve performance,
|
||||
migrate platforms, or fully rebuild your site with a better
|
||||
structure and codebase.
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
<AccordionItem value="item-5">
|
||||
<AccordionTrigger>
|
||||
Do you offer SEO and performance optimization?
|
||||
</AccordionTrigger>
|
||||
<AccordionContent>
|
||||
Yes! All our builds include basic SEO best practices and speed
|
||||
optimization. We also offer advanced technical SEO, Core Web
|
||||
Vitals tuning, and image/code optimization.
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
<AccordionItem value="item-6">
|
||||
<AccordionTrigger>
|
||||
Do you provide ongoing maintenance and support?
|
||||
</AccordionTrigger>
|
||||
<AccordionContent>
|
||||
Yes, we offer monthly maintenance plans for updates, backups,
|
||||
security checks, and minor edits. We can also provide on-demand
|
||||
support when needed.
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
<AccordionItem value="item-7">
|
||||
<AccordionTrigger>
|
||||
Will my site work on mobile devices?
|
||||
</AccordionTrigger>
|
||||
<AccordionContent>
|
||||
Definitely. Every site we build is fully responsive and tested
|
||||
on a variety of devices to ensure it looks great and works well
|
||||
on phones, tablets, and desktops.
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
<AccordionItem value="item-8">
|
||||
<AccordionTrigger>
|
||||
What do you need from me to get started?
|
||||
</AccordionTrigger>
|
||||
<AccordionContent>
|
||||
We’ll need some info about your goals, brand, content (text,
|
||||
images, logo), and examples of sites you like. Don’t worry—we’ll
|
||||
guide you through the process!
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
</Accordion>
|
||||
</section>
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import * as AccordionPrimitive from "@radix-ui/react-accordion"
|
||||
import { ChevronDownIcon } from "lucide-react"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
function Accordion({
|
||||
...props
|
||||
}) {
|
||||
return <AccordionPrimitive.Root data-slot="accordion" {...props} />;
|
||||
}
|
||||
|
||||
function AccordionItem({
|
||||
className,
|
||||
...props
|
||||
}) {
|
||||
return (
|
||||
<AccordionPrimitive.Item
|
||||
data-slot="accordion-item"
|
||||
className={cn("border-b last:border-b-0", className)}
|
||||
{...props} />
|
||||
);
|
||||
}
|
||||
|
||||
function AccordionTrigger({
|
||||
className,
|
||||
children,
|
||||
...props
|
||||
}) {
|
||||
return (
|
||||
<AccordionPrimitive.Header className="flex">
|
||||
<AccordionPrimitive.Trigger
|
||||
data-slot="accordion-trigger"
|
||||
className={cn(
|
||||
"focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-start justify-between gap-4 rounded-md py-4 text-left text-sm font-medium transition-all outline-none hover:underline focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&[data-state=open]>svg]:rotate-180",
|
||||
className
|
||||
)}
|
||||
{...props}>
|
||||
{children}
|
||||
<ChevronDownIcon
|
||||
className="text-muted-foreground pointer-events-none size-4 shrink-0 translate-y-0.5 transition-transform duration-200" />
|
||||
</AccordionPrimitive.Trigger>
|
||||
</AccordionPrimitive.Header>
|
||||
);
|
||||
}
|
||||
|
||||
function AccordionContent({
|
||||
className,
|
||||
children,
|
||||
...props
|
||||
}) {
|
||||
return (
|
||||
<AccordionPrimitive.Content
|
||||
data-slot="accordion-content"
|
||||
className="data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down overflow-hidden text-sm"
|
||||
{...props}>
|
||||
<div className={cn("pt-0 pb-4", className)}>{children}</div>
|
||||
</AccordionPrimitive.Content>
|
||||
);
|
||||
}
|
||||
|
||||
export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }
|
||||
@@ -0,0 +1,6 @@
|
||||
import { clsx } from "clsx";
|
||||
import { twMerge } from "tailwind-merge"
|
||||
|
||||
export function cn(...inputs) {
|
||||
return twMerge(clsx(inputs));
|
||||
}
|
||||
Reference in New Issue
Block a user