add some php host api and add hire developer and ai agent page
parent
63c973f1ca
commit
d2f3576d10
|
@ -10,14 +10,17 @@
|
|||
"dependencies": {
|
||||
"@astrojs/react": "^4.2.1",
|
||||
"@astrojs/tailwind": "^6.0.0",
|
||||
"@radix-ui/react-dialog": "^1.1.6",
|
||||
"@shadcn/ui": "^0.0.4",
|
||||
"astro": "^5.5.2",
|
||||
"autoprefixer": "^10.4.21",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"lucide-react": "^0.484.0",
|
||||
"postcss": "^8.5.3",
|
||||
"tailwind-merge": "^3.0.2",
|
||||
"tailwindcss": "^3.4.17"
|
||||
"tailwindcss": "^3.4.17",
|
||||
"tailwindcss-animate": "^1.0.7"
|
||||
}
|
||||
},
|
||||
"node_modules/@alloc/quick-lru": {
|
||||
|
@ -1359,6 +1362,318 @@
|
|||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"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-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-dialog": {
|
||||
"version": "1.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.6.tgz",
|
||||
"integrity": "sha512-/IVhJV5AceX620DUJ4uYVMymzsipdKBzo3edo+omeskCKGm9FRHM0ebIdbPnlQVJqyuHbuBltQUOG2mOTq2IYw==",
|
||||
"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-dismissable-layer": "1.1.5",
|
||||
"@radix-ui/react-focus-guards": "1.1.1",
|
||||
"@radix-ui/react-focus-scope": "1.1.2",
|
||||
"@radix-ui/react-id": "1.1.0",
|
||||
"@radix-ui/react-portal": "1.1.4",
|
||||
"@radix-ui/react-presence": "1.1.2",
|
||||
"@radix-ui/react-primitive": "2.0.2",
|
||||
"@radix-ui/react-slot": "1.1.2",
|
||||
"@radix-ui/react-use-controllable-state": "1.1.0",
|
||||
"aria-hidden": "^1.2.4",
|
||||
"react-remove-scroll": "^2.6.3"
|
||||
},
|
||||
"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-dismissable-layer": {
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.5.tgz",
|
||||
"integrity": "sha512-E4TywXY6UsXNRhFrECa5HAvE5/4BFcGyfTyK36gP+pAW1ed7UTK4vKwdr53gAJYwqbfCWC6ATvJa3J3R/9+Qrg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/primitive": "1.1.1",
|
||||
"@radix-ui/react-compose-refs": "1.1.1",
|
||||
"@radix-ui/react-primitive": "2.0.2",
|
||||
"@radix-ui/react-use-callback-ref": "1.1.0",
|
||||
"@radix-ui/react-use-escape-keydown": "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-focus-guards": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.1.tgz",
|
||||
"integrity": "sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg==",
|
||||
"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-focus-scope": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.2.tgz",
|
||||
"integrity": "sha512-zxwE80FCU7lcXUGWkdt6XpTTCKPitG1XKOwViTxHVKIJhZl9MvIl2dVHeZENCWD9+EdWv05wlaEkRXUykU27RA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-compose-refs": "1.1.1",
|
||||
"@radix-ui/react-primitive": "2.0.2",
|
||||
"@radix-ui/react-use-callback-ref": "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-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-portal": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.4.tgz",
|
||||
"integrity": "sha512-sn2O9k1rPFYVyKd5LAJfo96JlSGVFpa1fS6UuBJfrZadudiw5tAmru+n1x7aMRQ84qDM71Zh1+SzK5QwU0tJfA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-primitive": "2.0.2",
|
||||
"@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-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-escape-keydown": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz",
|
||||
"integrity": "sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==",
|
||||
"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/@rollup/pluginutils": {
|
||||
"version": "5.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz",
|
||||
|
@ -2009,6 +2324,18 @@
|
|||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
|
||||
"license": "Python-2.0"
|
||||
},
|
||||
"node_modules/aria-hidden": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz",
|
||||
"integrity": "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/aria-query": {
|
||||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz",
|
||||
|
@ -2724,6 +3051,12 @@
|
|||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/detect-node-es": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz",
|
||||
"integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/deterministic-object-hash": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/deterministic-object-hash/-/deterministic-object-hash-2.0.2.tgz",
|
||||
|
@ -3138,6 +3471,15 @@
|
|||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/get-nonce": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz",
|
||||
"integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/get-stream": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
|
||||
|
@ -3807,6 +4149,15 @@
|
|||
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/lucide-react": {
|
||||
"version": "0.484.0",
|
||||
"resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.484.0.tgz",
|
||||
"integrity": "sha512-oZy8coK9kZzvqhSgfbGkPtTgyjpBvs3ukLgDPv14dSOZtBtboryWF5o8i3qen7QbGg7JhiJBz5mK1p8YoMZTLQ==",
|
||||
"license": "ISC",
|
||||
"peerDependencies": {
|
||||
"react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/magic-string": {
|
||||
"version": "0.30.17",
|
||||
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz",
|
||||
|
@ -5339,6 +5690,75 @@
|
|||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-remove-scroll": {
|
||||
"version": "2.6.3",
|
||||
"resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.6.3.tgz",
|
||||
"integrity": "sha512-pnAi91oOk8g8ABQKGF5/M9qxmmOPxaAnopyTHYfqYEwJhyFrbbBtHuSgtKEoH0jpcxx5o3hXqH1mNd9/Oi+8iQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"react-remove-scroll-bar": "^2.3.7",
|
||||
"react-style-singleton": "^2.2.3",
|
||||
"tslib": "^2.1.0",
|
||||
"use-callback-ref": "^1.3.3",
|
||||
"use-sidecar": "^1.1.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/react-remove-scroll-bar": {
|
||||
"version": "2.3.8",
|
||||
"resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz",
|
||||
"integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"react-style-singleton": "^2.2.2",
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/react-style-singleton": {
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz",
|
||||
"integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"get-nonce": "^1.0.0",
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/read-cache": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
|
||||
|
@ -6139,6 +6559,15 @@
|
|||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/tailwindcss-animate": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss-animate/-/tailwindcss-animate-1.0.7.tgz",
|
||||
"integrity": "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"tailwindcss": ">=3.0.0 || insiders"
|
||||
}
|
||||
},
|
||||
"node_modules/tailwindcss/node_modules/chokidar": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
|
||||
|
@ -6304,8 +6733,7 @@
|
|||
"version": "2.8.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
||||
"license": "0BSD",
|
||||
"optional": true
|
||||
"license": "0BSD"
|
||||
},
|
||||
"node_modules/type-fest": {
|
||||
"version": "4.37.0",
|
||||
|
@ -6624,6 +7052,49 @@
|
|||
"browserslist": ">= 4.21.0"
|
||||
}
|
||||
},
|
||||
"node_modules/use-callback-ref": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz",
|
||||
"integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/use-sidecar": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz",
|
||||
"integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"detect-node-es": "^1.1.0",
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
|
|
|
@ -12,14 +12,17 @@
|
|||
"dependencies": {
|
||||
"@astrojs/react": "^4.2.1",
|
||||
"@astrojs/tailwind": "^6.0.0",
|
||||
"@radix-ui/react-dialog": "^1.1.6",
|
||||
"@shadcn/ui": "^0.0.4",
|
||||
"astro": "^5.5.2",
|
||||
"autoprefixer": "^10.4.21",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"lucide-react": "^0.484.0",
|
||||
"postcss": "^8.5.3",
|
||||
"tailwind-merge": "^3.0.2",
|
||||
"tailwindcss": "^3.4.17"
|
||||
"tailwindcss": "^3.4.17",
|
||||
"tailwindcss-animate": "^1.0.7"
|
||||
},
|
||||
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ export const DomainSetupForm = ({ defaultSubdomain }) => {
|
|||
const [customDomain, setCustomDomain] = useState('');
|
||||
const [customSubdomain, setCustomSubdomain] = useState('');
|
||||
const [domainType, setDomainType] = useState('domain'); // 'domain' or 'subdomain'
|
||||
|
||||
|
||||
// Domain validation states
|
||||
const [isValidating, setIsValidating] = useState(false);
|
||||
const [isValidDomain, setIsValidDomain] = useState(false);
|
||||
|
@ -43,15 +43,6 @@ export const DomainSetupForm = ({ defaultSubdomain }) => {
|
|||
// File upload reference
|
||||
const fileInputRef = React.useRef(null);
|
||||
|
||||
// Function to clean domain input
|
||||
const cleanDomainInput = (input) => {
|
||||
// Remove http://, https://, www., and trailing slashes
|
||||
return input
|
||||
.replace(/^(https?:\/\/)?(www\.)?/i, '')
|
||||
.replace(/\/+$/, '')
|
||||
.trim();
|
||||
};
|
||||
|
||||
// Effect for handling domain type changes
|
||||
useEffect(() => {
|
||||
if (!useCustomDomain) {
|
||||
|
@ -140,12 +131,12 @@ export const DomainSetupForm = ({ defaultSubdomain }) => {
|
|||
|
||||
// Handle domain and subdomain input changes
|
||||
const handleDomainChange = (e) => {
|
||||
const cleanedValue = cleanDomainInput(e.target.value);
|
||||
const cleanedValue = e.target.value.replace(/^(https?:\/\/)?(www\.)?/i, '').replace(/\/+$/, '').trim();
|
||||
setCustomDomain(cleanedValue);
|
||||
};
|
||||
|
||||
const handleSubdomainChange = (e) => {
|
||||
const cleanedValue = cleanDomainInput(e.target.value);
|
||||
const cleanedValue = e.target.value.replace(/^(https?:\/\/)?/i, '').replace(/\/+$/, '').trim();
|
||||
setCustomSubdomain(cleanedValue);
|
||||
};
|
||||
|
||||
|
@ -210,6 +201,38 @@ export const DomainSetupForm = ({ defaultSubdomain }) => {
|
|||
};
|
||||
|
||||
// Check DNS configuration
|
||||
const checkSubDomainCname = () => {
|
||||
const domainToCheck = customDomain || customSubdomain;
|
||||
|
||||
fetch('http://localhost:2058/host-api/v1/check-c-name/', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
body: `domain=${encodeURIComponent(domainToCheck)}`
|
||||
})
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then(data => {
|
||||
if (data.status === 'success') {
|
||||
checkDnsConfig('cname');
|
||||
showToast(`Checking ${type}... (This would verify DNS in a real app)`);
|
||||
console.log('CNAME record:', data.cname);
|
||||
// Handle success - update UI
|
||||
} else {
|
||||
console.error('Error:', data.message);
|
||||
// Handle error
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Fetch error:', error);
|
||||
// Show error to user
|
||||
});
|
||||
};
|
||||
const checkDnsConfig = (type) => {
|
||||
showToast(`Checking ${type}... (This would verify DNS in a real app)`);
|
||||
|
||||
|
@ -544,10 +567,10 @@ export const DomainSetupForm = ({ defaultSubdomain }) => {
|
|||
|
||||
{/* Domain Validation */}
|
||||
<button
|
||||
disabled={!customDomain}
|
||||
disabled={!customDomain && !customSubdomain}
|
||||
type="button"
|
||||
onClick={validateDomain}
|
||||
className={`px-4 py-2 ${!customDomain ? 'bg-neutral-600 cursor-not-allowed' : 'bg-[#6d9e37] focus:ring-[#6d9e37] transition-colors'} text-white font-medium rounded-md transition-colors focus:outline-none`}
|
||||
className={`px-4 py-2 ${ !customDomain && !customSubdomain ? 'bg-neutral-600 cursor-not-allowed' : 'bg-[#6d9e37] focus:ring-[#6d9e37] transition-colors'} text-white font-medium rounded-md transition-colors focus:outline-none`}
|
||||
>
|
||||
Validate Domain
|
||||
</button>
|
||||
|
@ -607,7 +630,7 @@ export const DomainSetupForm = ({ defaultSubdomain }) => {
|
|||
<div className="mt-2 text-right">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => checkDnsConfig('cname')}
|
||||
onClick={() => (checkSubDomainCname())}
|
||||
className={`px-3 py-1 text-white text-sm rounded
|
||||
${dnsVerified.cname
|
||||
? 'bg-green-700 hover:bg-green-600'
|
||||
|
|
|
@ -0,0 +1,333 @@
|
|||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "./ui/card";
|
||||
import { Button } from "./ui/button";
|
||||
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "./ui/dialog";
|
||||
import { Input } from "./ui/input";
|
||||
|
||||
// Define the AI Agent type
|
||||
interface AIAgent {
|
||||
id: number;
|
||||
title: string;
|
||||
description: string;
|
||||
capabilities: string[];
|
||||
responseTime: string;
|
||||
pricing: string;
|
||||
useCases: string[];
|
||||
}
|
||||
|
||||
// AI Agent types data
|
||||
const aiAgentTypes: AIAgent[] = [
|
||||
{
|
||||
id: 1,
|
||||
title: "Code Assistant",
|
||||
description: "AI-powered coding assistant that helps write, debug, and optimize code across multiple languages",
|
||||
capabilities: ["Code Generation", "Code Review", "Bug Detection", "Code Explanation", "Documentation"],
|
||||
responseTime: "Instant",
|
||||
pricing: "$29/month",
|
||||
useCases: ["Software Development", "Web Development", "Mobile Apps", "Enterprise Applications"]
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: "Data Analyst",
|
||||
description: "Specialized AI for data analytics, visualization, and insights extraction",
|
||||
capabilities: ["Data Cleaning", "Statistical Analysis", "Data Visualization", "Predictive Modeling"],
|
||||
responseTime: "Within minutes",
|
||||
pricing: "$49/month",
|
||||
useCases: ["Business Intelligence", "Market Research", "Financial Analysis", "Customer Insights"]
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: "Content Creator",
|
||||
description: "AI agent for generating and optimizing various types of content",
|
||||
capabilities: ["Blog Writing", "Social Media Content", "Email Marketing", "SEO Optimization"],
|
||||
responseTime: "Instant to minutes",
|
||||
pricing: "$39/month",
|
||||
useCases: ["Marketing Teams", "Content Publishers", "Social Media Managers", "Small Businesses"]
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
title: "UI/UX Design Assistant",
|
||||
description: "AI that helps create design mockups, wireframes, and UI elements",
|
||||
capabilities: ["Wireframing", "UI Design", "Visual Elements", "Design Feedback"],
|
||||
responseTime: "Within minutes",
|
||||
pricing: "$59/month",
|
||||
useCases: ["Product Teams", "Web Designers", "App Developers", "Creative Agencies"]
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
title: "Research Assistant",
|
||||
description: "AI agent that helps with research, information gathering, and summarization",
|
||||
capabilities: ["Literature Review", "Data Collection", "Summarization", "Citation Management"],
|
||||
responseTime: "Within minutes",
|
||||
pricing: "$45/month",
|
||||
useCases: ["Academic Research", "Market Research", "Competitive Analysis", "Legal Research"]
|
||||
}
|
||||
];
|
||||
|
||||
export default function HireAIAgent() {
|
||||
const [selectedAgent, setSelectedAgent] = useState<AIAgent | null>(null);
|
||||
const [dialogOpen, setDialogOpen] = useState(false);
|
||||
const [searchTerm, setSearchTerm] = useState("");
|
||||
|
||||
// Filter AI agents based on search term
|
||||
const filteredAgents = aiAgentTypes.filter(agent =>
|
||||
agent.title.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||
agent.description.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||
agent.capabilities.some(cap => cap.toLowerCase().includes(searchTerm.toLowerCase())) ||
|
||||
agent.useCases.some(useCase => useCase.toLowerCase().includes(searchTerm.toLowerCase()))
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="container mx-auto px-4 py-12">
|
||||
<h1 className="text-center text-3xl sm:text-4xl font-bold text-[#6d9e37] mb-3 sm:mb-4">Hire an AI Agent</h1>
|
||||
<p className="text-center text-lg sm:text-xl max-w-3xl mx-auto text-neutral-300 mb-10">
|
||||
Leverage our AI agents to automate tasks, generate content, analyze data, and more
|
||||
</p>
|
||||
|
||||
{/* Hero Banner */}
|
||||
<div className="bg-neutral-800 text-white rounded-lg p-8 mb-12">
|
||||
<div className="flex flex-col md:flex-row md:items-center">
|
||||
<div className="md:w-2/3 mb-6 md:mb-0 md:pr-6">
|
||||
<h2 className="text-2xl md:text-3xl font-bold mb-4 text-[#6d9e37]">Why Choose AI Agents?</h2>
|
||||
<p className="mb-4">
|
||||
Our AI agents work 24/7, provide instant results, and cost a fraction of human labor. They excel at repetitive tasks, data processing, and creative content generation.
|
||||
</p>
|
||||
<div className="grid grid-cols-2 gap-4 mt-6">
|
||||
<div className="flex items-start">
|
||||
<div className="bg-white bg-opacity-20 p-2 rounded mr-3">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" viewBox="0 0 20 20" fill="#6d9e37">
|
||||
<path fillRule="evenodd" d="M11.3 1.046A1 1 0 0112 2v5h4a1 1 0 01.82 1.573l-7 10A1 1 0 018 18v-5H4a1 1 0 01-.82-1.573l7-10a1 1 0 011.12-.38z" clipRule="evenodd" />
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-sm">Instant Results</h3>
|
||||
<p className="text-xs text-zinc-300">No waiting for human availability</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-start">
|
||||
<div className="bg-white bg-opacity-20 p-2 rounded mr-3">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" viewBox="0 0 20 20" fill="#6d9e37">
|
||||
<path fillRule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clipRule="evenodd" />
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-sm">Cost Effective</h3>
|
||||
<p className="text-xs text-zinc-300">Fraction of human labor costs</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="md:w-1/3">
|
||||
<div className="bg-white bg-opacity-10 p-6 rounded-lg text-center">
|
||||
<h3 className="font-bold mb-2">Start with an AI Agent Today</h3>
|
||||
<p className="text-sm mb-4 text-zinc-300">
|
||||
All plans come with a 7-day free trial
|
||||
</p>
|
||||
<Button className="w-full">View All Agents</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Search */}
|
||||
<div className="mb-8">
|
||||
<div className="max-w-md mx-auto">
|
||||
<Input
|
||||
type="text"
|
||||
placeholder="Search AI agents by capability or use case..."
|
||||
value={searchTerm}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
className="mb-4"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* AI Agent Grid */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
{filteredAgents.map((agent) => (
|
||||
<Card key={agent.id} className="hover:shadow-md transition">
|
||||
<CardHeader>
|
||||
<CardTitle>{agent.title}</CardTitle>
|
||||
<CardDescription>{agent.description}</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="mb-4">
|
||||
<h4 className="text-sm font-semibold mb-2">Key Capabilities:</h4>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{agent.capabilities.map((capability, index) => (
|
||||
<span
|
||||
key={index}
|
||||
className="inline-block bg-zinc-100 text-zinc-800 text-xs px-2 py-1 rounded"
|
||||
>
|
||||
{capability}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-2 text-sm">
|
||||
<div className="flex justify-between">
|
||||
<span className="text-zinc-500">Response Time:</span>
|
||||
<span className="font-medium text-green-600">{agent.responseTime}</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="text-zinc-500">Pricing:</span>
|
||||
<span className="font-medium">{agent.pricing}</span>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<Button className="w-full" onClick={() => {setSelectedAgent(agent); setDialogOpen(true);}}>View Details</Button>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* AI Agent Details Dialog */}
|
||||
<Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
|
||||
<DialogContent className="sm:max-w-md">
|
||||
{selectedAgent && (
|
||||
<>
|
||||
<DialogHeader>
|
||||
<DialogTitle>{selectedAgent.title}</DialogTitle>
|
||||
<DialogDescription>
|
||||
{selectedAgent.description}
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<div className="space-y-4 py-4">
|
||||
<div>
|
||||
<h4 className="text-sm font-semibold mb-1">Capabilities:</h4>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{selectedAgent.capabilities.map((capability, index) => (
|
||||
<span
|
||||
key={index}
|
||||
className="inline-block bg-zinc-100 text-zinc-800 text-xs px-2 py-1 rounded"
|
||||
>
|
||||
{capability}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h4 className="text-sm font-semibold mb-1">Common Use Cases:</h4>
|
||||
<ul className="list-disc pl-5 text-zinc-600 text-sm">
|
||||
{selectedAgent.useCases.map((useCase, index) => (
|
||||
<li key={index}>{useCase}</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
<h4 className="text-sm font-semibold mb-1">Response Time:</h4>
|
||||
<p className="font-medium text-green-600">{selectedAgent.responseTime}</p>
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="text-sm font-semibold mb-1">Pricing:</h4>
|
||||
<p className="font-medium">{selectedAgent.pricing}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="border-t border-gray-200 pt-4">
|
||||
<h4 className="text-sm font-semibold mb-1">Subscription Includes:</h4>
|
||||
<ul className="text-sm text-zinc-600 space-y-1">
|
||||
<li className="flex items-center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4 text-green-500 mr-2" viewBox="0 0 20 20" fill="#6d9e37">
|
||||
<path fillRule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clipRule="evenodd" />
|
||||
</svg>
|
||||
Unlimited requests
|
||||
</li>
|
||||
<li className="flex items-center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4 text-green-500 mr-2" viewBox="0 0 20 20" fill="#6d9e37">
|
||||
<path fillRule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clipRule="evenodd" />
|
||||
</svg>
|
||||
24/7 availability
|
||||
</li>
|
||||
<li className="flex items-center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4 text-green-500 mr-2" viewBox="0 0 20 20" fill="#6d9e37">
|
||||
<path fillRule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clipRule="evenodd" />
|
||||
</svg>
|
||||
API access
|
||||
</li>
|
||||
<li className="flex items-center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4 text-green-500 mr-2" viewBox="0 0 20 20" fill="#6d9e37">
|
||||
<path fillRule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clipRule="evenodd" />
|
||||
</svg>
|
||||
Export capabilities
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<DialogFooter>
|
||||
<Button type="button" variant="outline" onClick={() => setDialogOpen(false)}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button type="button">
|
||||
Subscribe Now
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</>
|
||||
)}
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
{/* Comparison Section */}
|
||||
<div className="mt-16">
|
||||
<h2 className="text-2xl font-bold mb-8 text-center">AI Agents vs. Human Developers</h2>
|
||||
<div className="overflow-x-auto">
|
||||
<table className="w-full border-collapse">
|
||||
<thead>
|
||||
<tr className="bg-neutral-800 text-white">
|
||||
<th className="p-4 text-center border-[1px] border-[#6d9e37] w-1/3">Feature</th>
|
||||
<th className="p-4 text-center border-[1px] border-[#6d9e37] w-1/3">AI Agents</th>
|
||||
<th className="p-4 text-center border-[1px] border-[#6d9e37] w-1/3">Human Developers</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className="p-4 border-[1px] border-[#6d9e37] font-medium">Availability</td>
|
||||
<td className="p-4 border-[1px] border-[#6d9e37]">24/7, instant access</td>
|
||||
<td className="p-4 border-[1px] border-[#6d9e37]">Limited by working hours and availability</td>
|
||||
</tr>
|
||||
<tr className="bg-neutral-800 text-white">
|
||||
<td className="p-4 border-[1px] border-[#6d9e37] font-medium">Cost</td>
|
||||
<td className="p-4 border-[1px] border-[#6d9e37]">Low monthly subscription</td>
|
||||
<td className="p-4 border-[1px] border-[#6d9e37]">Higher hourly or project-based rates</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="p-4 border-[1px] border-[#6d9e37] font-medium">Task Complexity</td>
|
||||
<td className="p-4 border-[1px] border-[#6d9e37]">Best for repetitive, well-defined tasks</td>
|
||||
<td className="p-4 border-[1px] border-[#6d9e37]">Better for complex, novel problems</td>
|
||||
</tr>
|
||||
<tr className="bg-neutral-800 text-white">
|
||||
<td className="p-4 border-[1px] border-[#6d9e37] font-medium">Creativity</td>
|
||||
<td className="p-4 border-[1px] border-[#6d9e37]">Limited to patterns in training data</td>
|
||||
<td className="p-4 border-[1px] border-[#6d9e37]">Higher level of creativity and innovation</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="p-4 border-[1px] border-[#6d9e37] font-medium">Scalability</td>
|
||||
<td className="p-4 border-[1px] border-[#6d9e37]">Highly scalable at no extra cost</td>
|
||||
<td className="p-4 border-[1px] border-[#6d9e37]">Requires additional hiring and onboarding</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* CTA Section */}
|
||||
<div className="mt-16 bg-neutral-800 p-8 rounded-lg text-center">
|
||||
<h2 className="text-2xl font-bold mb-4 text-[#6d9e37]">Not sure which AI agent is right for you?</h2>
|
||||
<p className="text-neutral-300 max-w-2xl mx-auto mb-8">
|
||||
Our AI solution experts can help you determine which AI agent best fits your specific needs and use cases.
|
||||
</p>
|
||||
<Button size="lg">
|
||||
Schedule a Consultation
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,263 @@
|
|||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "./ui/card";
|
||||
import { Button } from "./ui/button";
|
||||
import { Input } from "./ui/input";
|
||||
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "./ui/dialog";
|
||||
|
||||
// Define the Developer type
|
||||
interface Developer {
|
||||
id: number;
|
||||
title: string;
|
||||
description: string;
|
||||
skills: string[];
|
||||
availability: "High" | "Medium" | "Low";
|
||||
minBudget: string;
|
||||
contractFee: string;
|
||||
}
|
||||
|
||||
// Developer types data
|
||||
const developerTypes: Developer[] = [
|
||||
{
|
||||
id: 1,
|
||||
title: "Web Developer",
|
||||
description: "Frontend, backend or full-stack developers specialized in web technologies",
|
||||
skills: ["React", "Angular", "Vue", "Node.js", "Django", "Ruby on Rails", "Laravel", "Express", "Flask", "PHP", "JavaScript", "TypeScript", "HTML", "CSS", "SASS", "LESS", "Bootstrap", "Tailwind CSS", "Material-UI", "Ant Design", "REST APIs", "GraphQL", "WebSockets", "OAuth", "JWT", "WebRTC", "PWA", "SEO", "Accessibility", "Performance", "Security"],
|
||||
availability: "High",
|
||||
minBudget: "Budget-friendly",
|
||||
contractFee: "Nominal"
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: "App Developer",
|
||||
description: "iOS and Android native or cross-platform mobile app developers",
|
||||
skills: ["Swift", "Kotlin", "React Native", "Flutter", "Xamarin", "Ionic", "PhoneGap", "Cordova", "NativeScript", "Appcelerator", "Java", "Objective-C", "Firebase", "Realm", "Core Data", "SQLite", "Push Notifications", "In-App Purchases", "ARKit", "Core ML", "Android Jetpack", "Material Design", "Google Play Services", "App Store Connect", "Google Play Console"],
|
||||
availability: "Medium",
|
||||
minBudget: "Limited",
|
||||
contractFee: "Modest"
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: "C/C++ Developer",
|
||||
description: "Systems programmers and embedded systems specialists",
|
||||
skills: ["C", "C++", "Embedded Systems", "Linux Kernel", "Real-time Systems", "RTOS", "Device Drivers", "Firmware", "Microcontrollers", "ARM", "AVR", "PIC", "Raspberry Pi", "Arduino", "BeagleBone", "Zephyr", "FreeRTOS", "VxWorks", "QNX", "Bare Metal"],
|
||||
availability: "Low",
|
||||
minBudget: "Increased",
|
||||
contractFee: "Considerable"
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
title: "Go Developer",
|
||||
description: "Backend and systems engineers specializing in Go language",
|
||||
skills: ["Go", "Microservices", "Docker", "Kubernetes", "API Development", "gRPC", "Protobuf", "WebSockets", "WebAssembly", "Concurrency", "Performance Tuning", "Module Building", "Error Handling", "Testing", "Security"],
|
||||
availability: "Medium",
|
||||
minBudget: "Boosted",
|
||||
contractFee: "Elevated"
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
title: "Machine Learning Engineer",
|
||||
description: "AI and ML specialists for implementing intelligent solutions",
|
||||
skills: ["Python", "TensorFlow", "PyTorch", "Data Science", "MLOps", "NLP", "Computer Vision", "Reinforcement Learning", "Time Series Analysis", "Anomaly Detection", "Recommendation Systems", "Predictive Modeling", "Deep Learning", "Fraud Detection", "Sentiment Analysis", "Speech Recognition", "Image Processing", "Object Detection", "Generative Models", "AutoML", "Image Recognition", "Text Classification", "Chatbots", "AI Ethics"],
|
||||
availability: "Low",
|
||||
minBudget: "Premium",
|
||||
contractFee: "Lavish"
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
title: "DevOps Engineer",
|
||||
description: "Specialists in CI/CD, cloud infrastructure, and deployment automation",
|
||||
skills: ["AWS", "Azure", "GCP", "Terraform", "Ansible", "Jenkins", "Docker", "Kubernetes", "GitOps", "Monitoring", "Logging", "Security", "Compliance", "Scalability", "Reliability", "Resilience", "Performance", "Cost Optimization", "Disaster Recovery", "Incident Response", "SRE"],
|
||||
availability: "Medium",
|
||||
minBudget: "Pricier",
|
||||
contractFee: "Substantial"
|
||||
}
|
||||
];
|
||||
|
||||
export default function HireHumanDeveloper() {
|
||||
const [selectedType, setSelectedType] = useState<Developer | null>(null);
|
||||
const [searchTerm, setSearchTerm] = useState("");
|
||||
const [dialogOpen, setDialogOpen] = useState(false);
|
||||
|
||||
// Filter developers based on search term
|
||||
const filteredDevelopers = developerTypes.filter(dev =>
|
||||
dev.title.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||
dev.description.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||
dev.skills.some(skill => skill.toLowerCase().includes(searchTerm.toLowerCase()))
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="container mx-auto px-4 py-12">
|
||||
<h1 className="text-center text-3xl sm:text-4xl font-bold text-[#6d9e37] mb-3 sm:mb-4">Hire a Human Developer</h1>
|
||||
<p className="text-center text-lg sm:text-xl max-w-3xl mx-auto text-neutral-300 mb-10">
|
||||
Connect with skilled developers across various technologies and specialties
|
||||
</p>
|
||||
|
||||
{/* Search and Filter */}
|
||||
<div className="mb-8">
|
||||
<div className="max-w-md mx-auto">
|
||||
<Input
|
||||
type="text"
|
||||
placeholder="Search by technology, skill, or type..."
|
||||
value={searchTerm}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
className="mb-4"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Developer Types Grid */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
{filteredDevelopers.map((developer) => (
|
||||
<Card key={developer.id} className="hover:shadow-md transition">
|
||||
<CardHeader>
|
||||
<CardTitle>{developer.title}</CardTitle>
|
||||
<CardDescription>{developer.description}</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="mb-4">
|
||||
<h4 className="text-sm font-semibold mb-2 text-neutral-300">Key Skills:</h4>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{developer.skills.map((skill, index) => (
|
||||
<span
|
||||
key={index}
|
||||
className="inline-block bg-neutral-300 text-zinc-800 text-xs px-2 py-1 rounded"
|
||||
>
|
||||
{skill}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-2 text-sm">
|
||||
<div className="flex justify-between">
|
||||
<span className="text-zinc-500">Availability:</span>
|
||||
<span className={`font-medium ${
|
||||
developer.availability === "High" ? "text-green-600" :
|
||||
developer.availability === "Medium" ? "text-amber-600" : "text-red-600"
|
||||
}`}>
|
||||
{developer.availability}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="text-zinc-500">Starting at:</span>
|
||||
<span className="font-medium">{developer.minBudget}</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="text-zinc-500">Contract Fee:</span>
|
||||
<span className="font-medium">{developer.contractFee}</span>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<Button
|
||||
className="w-full"
|
||||
onClick={() => {
|
||||
setSelectedType(developer);
|
||||
setDialogOpen(true);
|
||||
}}
|
||||
>
|
||||
Hire Developer
|
||||
</Button>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Developer Details Dialog */}
|
||||
<Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
|
||||
<DialogContent className="sm:max-w-md">
|
||||
{selectedType && (
|
||||
<>
|
||||
<DialogHeader>
|
||||
<DialogTitle>{selectedType.title} Details</DialogTitle>
|
||||
<DialogDescription>
|
||||
Review the details and proceed to hire
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<div className="space-y-4 py-4">
|
||||
<div>
|
||||
<h4 className="text-sm font-semibold mb-1 text-neutral-950">Overview:</h4>
|
||||
<p className="text-neutral-400">{selectedType.description}</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h4 className="text-sm font-semibold mb-1 text-neutral-950">Specialized Skills:</h4>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{selectedType.skills.map((skill, index) => (
|
||||
<span
|
||||
key={index}
|
||||
className="inline-block bg-zinc-100 text-zinc-800 text-xs px-2 py-1 rounded"
|
||||
>
|
||||
{skill}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
<h4 className="text-sm font-semibold mb-1 text-neutral-950">Availability:</h4>
|
||||
<p className={`font-medium ${
|
||||
selectedType.availability === "High" ? "text-green-600" :
|
||||
selectedType.availability === "Medium" ? "text-amber-600" : "text-red-600"
|
||||
}`}>
|
||||
{selectedType.availability}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="text-sm font-semibold mb-1 text-neutral-950">Minimum Budget:</h4>
|
||||
<p className="font-medium text-neutral-950">{selectedType.minBudget}</p>
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="text-sm font-semibold mb-1 text-neutral-950">Contract Fee:</h4>
|
||||
<p className="font-medium text-neutral-950">{selectedType.contractFee}</p>
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="text-sm font-semibold mb-1 text-neutral-950">Usual Turnaround:</h4>
|
||||
<p className="font-medium text-neutral-950">1-3 weeks</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<DialogFooter>
|
||||
<Button type="button" variant="outline" onClick={() => setDialogOpen(false)}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button type="button">
|
||||
Proceed to Hire
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</>
|
||||
)}
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
{/* Additional Information */}
|
||||
<div className="mt-16 bg-neutral-800 p-8 rounded-lg">
|
||||
<h2 className="text-2xl font-bold mb-4 text-[#6d9e37]">Why Hire Our Human Developers?</h2>
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold mb-2 text-[#6d9e37]">Vetted Experts</h3>
|
||||
<p className="text-[#fff]">
|
||||
All our developers go through a rigorous vetting process to ensure top-quality talent.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold mb-2 text-[#6d9e37]">Flexible Engagement</h3>
|
||||
<p className="text-[#fff]">
|
||||
Hire on hourly, project-based, or long-term contracts based on your needs.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold mb-2 text-[#6d9e37]">Satisfaction Guarantee</h3>
|
||||
<p className="text-[#fff]">
|
||||
Not satisfied with the talent? We'll match you with another developer at no extra cost.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -36,7 +36,7 @@ export function ServiceCard({ title, description, imageUrl, features, learnMoreU
|
|||
>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
|
||||
</svg>
|
||||
<span>{feature}</span>
|
||||
<span className='text-zinc-600'>{feature}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
|
|
@ -8,7 +8,7 @@ const Card = React.forwardRef<
|
|||
<div
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"rounded-lg border border-neutral-200 bg-white text-neutral-950 shadow-sm dark:border-neutral-800 dark:bg-neutral-950 dark:text-neutral-50",
|
||||
"rounded-lg border border-[#6d9e37] bg-neutral-800 text-[#6d9e37] shadow-sm dark:border-neutral-800 dark:bg-neutral-950 dark:text-neutral-50",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import * as DialogPrimitive from "@radix-ui/react-dialog"
|
||||
import { X } from "lucide-react"
|
||||
|
||||
import { cn } from "../../lib/utils"
|
||||
|
||||
const Dialog = DialogPrimitive.Root
|
||||
|
||||
const DialogTrigger = DialogPrimitive.Trigger
|
||||
|
||||
const DialogPortal = DialogPrimitive.Portal
|
||||
|
||||
const DialogClose = DialogPrimitive.Close
|
||||
|
||||
const DialogOverlay = React.forwardRef<
|
||||
React.ElementRef<typeof DialogPrimitive.Overlay>,
|
||||
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<DialogPrimitive.Overlay
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName
|
||||
|
||||
const DialogContent = React.forwardRef<
|
||||
React.ElementRef<typeof DialogPrimitive.Content>,
|
||||
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
|
||||
>(({ className, children, ...props }, ref) => (
|
||||
<DialogPortal>
|
||||
<DialogOverlay />
|
||||
<DialogPrimitive.Content
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-[#fff] p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-[#fff] transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
|
||||
<X className="h-4 w-4 text-black" />
|
||||
<span className="sr-only">Close</span>
|
||||
</DialogPrimitive.Close>
|
||||
</DialogPrimitive.Content>
|
||||
</DialogPortal>
|
||||
))
|
||||
DialogContent.displayName = DialogPrimitive.Content.displayName
|
||||
|
||||
const DialogHeader = ({
|
||||
className,
|
||||
...props
|
||||
}: React.HTMLAttributes<HTMLDivElement>) => (
|
||||
<div
|
||||
className={cn(
|
||||
"flex flex-col space-y-1.5 text-center sm:text-left",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
DialogHeader.displayName = "DialogHeader"
|
||||
|
||||
const DialogFooter = ({
|
||||
className,
|
||||
...props
|
||||
}: React.HTMLAttributes<HTMLDivElement>) => (
|
||||
<div
|
||||
className={cn(
|
||||
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
DialogFooter.displayName = "DialogFooter"
|
||||
|
||||
const DialogTitle = React.forwardRef<
|
||||
React.ElementRef<typeof DialogPrimitive.Title>,
|
||||
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<DialogPrimitive.Title
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"text-lg font-semibold leading-none tracking-tight text-[#6d9e37]",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
DialogTitle.displayName = DialogPrimitive.Title.displayName
|
||||
|
||||
const DialogDescription = React.forwardRef<
|
||||
React.ElementRef<typeof DialogPrimitive.Description>,
|
||||
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<DialogPrimitive.Description
|
||||
ref={ref}
|
||||
className={cn("text-sm text-neutral-400", className)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
DialogDescription.displayName = DialogPrimitive.Description.displayName
|
||||
|
||||
export {
|
||||
Dialog,
|
||||
DialogPortal,
|
||||
DialogOverlay,
|
||||
DialogTrigger,
|
||||
DialogClose,
|
||||
DialogContent,
|
||||
DialogHeader,
|
||||
DialogFooter,
|
||||
DialogTitle,
|
||||
DialogDescription,
|
||||
}
|
|
@ -174,8 +174,8 @@ const organizationSchema = {
|
|||
<ul class="space-y-2 text-neutral-400">
|
||||
<li class="flex items-center gap-2">📦 <a href="/services" class="hover:text-[#6d9e37] transition-colors">All Services</a></li>
|
||||
<li class="flex items-center gap-2">🚀 <a href="/get-started" class="hover:text-[#6d9e37] transition-colors">Get Started</a></li>
|
||||
<li class="flex items-center gap-2">👨💻 <a href="/services/hire-developer" class="hover:text-[#6d9e37] transition-colors">Hire a Human Developer</a></li>
|
||||
<li class="flex items-center gap-2">🤖 <a href="/services/hire-ai-agent" class="hover:text-[#6d9e37] transition-colors">Hire an AI Agent</a></li>
|
||||
<li class="flex items-center gap-2">👨💻 <a href="/hire-developer" class="hover:text-[#6d9e37] transition-colors">Hire a Human Developer</a></li>
|
||||
<li class="flex items-center gap-2">🤖 <a href="/hire-ai-agent" class="hover:text-[#6d9e37] transition-colors">Hire an AI Agent</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import Layout from "../../layouts/Layout.astro"
|
|||
</div>
|
||||
|
||||
<script is:inline>
|
||||
fetch('/host-api/add-domain/')
|
||||
fetch('http://localhost:2058/host-api/v1/add-domain/')
|
||||
.then(response => {
|
||||
if (!response.ok) throw new Error('Network error');
|
||||
return response.json();
|
||||
|
|
|
@ -20,7 +20,7 @@ import Layout from "../../layouts/Layout.astro"
|
|||
responseElement.textContent = "Deleting domain...";
|
||||
|
||||
try {
|
||||
const response = await fetch('/host-api/delete-domain/', {
|
||||
const response = await fetch('http://localhost:2058/host-api/v1/delete-domain/', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
|
|
|
@ -7,7 +7,7 @@ import Layout from "../../layouts/Layout.astro"
|
|||
</div>
|
||||
|
||||
<script is:inline>
|
||||
fetch('/host-api/list-domain/')
|
||||
fetch('http://localhost:2058/host-api/v1/list-domain/')
|
||||
.then(response => {
|
||||
if (!response.ok) throw new Error('Network error');
|
||||
return response.json();
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
import Layout from "../layouts/Layout.astro";
|
||||
import HireAIAgent from "../components/HireAIAgent";
|
||||
---
|
||||
<Layout title="">
|
||||
<div>
|
||||
<HireAIAgent client:load />
|
||||
</div>
|
||||
</Layout>
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
import Layout from "../layouts/Layout.astro";
|
||||
import Developer from "../components/HireDeveloper";
|
||||
---
|
||||
<Layout title="">
|
||||
<div>
|
||||
<Developer client:load />
|
||||
</div>
|
||||
</Layout>
|
|
@ -10,43 +10,25 @@ const pageImage = "https://images.unsplash.com/photo-1551731409-43eb3e517a1a?q=8
|
|||
// Service data
|
||||
const services = [
|
||||
{
|
||||
title: 'PHP Hosting',
|
||||
description: 'Fast, secure, and reliable PHP hosting solutions for your web applications.',
|
||||
title: 'Deploy an App',
|
||||
description: 'WordPress, Joomla, Drupal, PrestaShop, Wiki, Moodle, Directus, PocketBase, StarAPI and more.',
|
||||
imageUrl: 'https://images.unsplash.com/photo-1599507593499-a3f7d7d97667?q=80&w=2000&auto=format&fit=crop',
|
||||
features: [
|
||||
'PHP 8.x support',
|
||||
'One-click installation of popular CMS',
|
||||
'Free SSL certificates',
|
||||
'Optimized for WordPress, Laravel, etc.',
|
||||
'24/7 Technical support'
|
||||
],
|
||||
learnMoreUrl: '/services/php'
|
||||
features: [ 'WordPress', 'Joomla', 'Drupal', 'PrestaShop', 'Wiki', 'Moodle', 'Directus', 'PocketBase', 'StarAPI' ],
|
||||
learnMoreUrl: '/services/deploy-an-app'
|
||||
},
|
||||
{
|
||||
title: 'Node.js Hosting',
|
||||
description: 'High-performance Node.js hosting with seamless deployment pipelines.',
|
||||
imageUrl: 'https://images.unsplash.com/photo-1570063578733-6a33b69d1538?q=80&w=2000&auto=format&fit=crop',
|
||||
features: [
|
||||
'Latest Node.js versions',
|
||||
'NPM/Yarn support',
|
||||
'Express, Next.js, and more',
|
||||
'Managed SSL certificates',
|
||||
'Automatic scaling'
|
||||
],
|
||||
learnMoreUrl: '/services/nodejs'
|
||||
title: 'Deploy From Source Code',
|
||||
description: 'Node.js, Python, Ruby, Go, Rust, and more. Deploy your custom applications with ease.',
|
||||
imageUrl: 'https://images.unsplash.com/photo-1599507593499-a3f7d7d97667?q=80&w=2000&auto=format&fit=crop',
|
||||
features: ['Node.js', 'Python', 'Ruby', 'Go', 'Rust', 'Docker', 'Kubernetes', 'JAMstack', 'Serverless'],
|
||||
learnMoreUrl: '/services/deploy-from-source-code'
|
||||
},
|
||||
{
|
||||
title: 'Python Hosting',
|
||||
description: 'Scalable Python hosting for web applications, APIs, and data science projects.',
|
||||
title: 'Static Site Hosting',
|
||||
description: 'Secure and scalable hosting for static websites and JAMstack applications.',
|
||||
imageUrl: 'https://images.unsplash.com/photo-1526379879527-8559ecfcaec0?q=80&w=2000&auto=format&fit=crop',
|
||||
features: [
|
||||
'Python 3.x support',
|
||||
'Django, Flask, and FastAPI ready',
|
||||
'Virtual environments',
|
||||
'Jupyter notebook integration',
|
||||
'Seamless deployment'
|
||||
],
|
||||
learnMoreUrl: '/services/python'
|
||||
features: ['JAMstack', 'Gatsby', 'Hugo', 'Next.js', 'Nuxt.js', 'VuePress', 'Eleventy', 'SvelteKit', 'Astro'],
|
||||
learnMoreUrl: '/services/static-site-hosting'
|
||||
},
|
||||
{
|
||||
title: 'Kubernetes (K8s)',
|
||||
|
@ -73,6 +55,20 @@ const services = [
|
|||
'Simplified management'
|
||||
],
|
||||
learnMoreUrl: '/services/k3s'
|
||||
},
|
||||
{
|
||||
title: 'Hire a Human Developer',
|
||||
description: 'Need a custom solution? Our experts can design a tailored App or WebApp for your specific needs.',
|
||||
imageUrl: 'https://images.unsplash.com/photo-1558494949-ef010cbdcc31?q=80&w=2000&auto=format&fit=crop',
|
||||
features: ['Node.js', 'Python', 'Ruby', 'Go', 'Rust', 'Docker', 'Kubernetes', 'JAMstack', 'Serverless'],
|
||||
learnMoreUrl: '/services/hire-a-human-developer'
|
||||
},
|
||||
{
|
||||
title: 'Hire an AI Agent',
|
||||
description: 'Need a custom solution? Our experts can design a tailored AI Agent for your specific needs.',
|
||||
imageUrl: 'https://images.unsplash.com/photo-1558494949-ef010cbdcc31?q=80&w=2000&auto=format&fit=crop',
|
||||
features: ['Reactive Agents (Stateless, Rule-Based)', 'Proactive Agents (Stateful, Machine Learning)', 'Hybrid Agents (Reactive + Proactive)', 'Model-Based Agents (Stateful, Uses Memory)', 'Goal-Based Agents (Optimizes for an Objective)', 'Utility-Based Agents', 'Self Learning Agents', 'Autonomous AI Agents'],
|
||||
learnMoreUrl: '/services/hire-an-ai-agent'
|
||||
}
|
||||
];
|
||||
---
|
||||
|
|
Loading…
Reference in New Issue