Browse Source

API connected , Staticks changed

main
sina_sajjadi 3 months ago
parent
commit
e5490dee8b
  1. 4
      .env.local.example
  2. 10
      next.config.js
  3. 358
      package-lock.json
  4. 4
      package.json
  5. 11
      public/لوگو3 1.svg
  6. 2
      src/app/(account-pages)/(components)/Nav.tsx
  7. 32
      src/app/(account-pages)/account-billing/page.tsx
  8. 196
      src/app/(account-pages)/account/page.tsx
  9. 55
      src/app/(account-pages)/passengers-list/PassengerTable.tsx
  10. 52
      src/app/(account-pages)/passengers-list/page.tsx
  11. 22
      src/app/(client-components)/(Header)/Header.tsx
  12. 42
      src/app/(client-components)/(Header)/MainNav1.tsx
  13. 13
      src/app/(client-components)/(Header)/SiteHeader.tsx
  14. 95
      src/app/(client-components)/(HeroSearchForm)/(stay-search-form)/StayDatesRangeInput.tsx
  15. 2
      src/app/(client-components)/(HeroSearchForm)/ButtonSubmit.tsx
  16. 62
      src/app/(client-components)/(HeroSearchForm)/GuestsInput.tsx
  17. 20
      src/app/(client-components)/(HeroSearchForm)/HeroSearchForm.tsx
  18. 70
      src/app/(client-components)/(HeroSearchForm)/LocationInput.tsx
  19. 2
      src/app/(listing-detail)/SectionDateRange.tsx
  20. 7
      src/app/(listing-detail)/layout.tsx
  21. 98
      src/app/add-listing/[[...stepIndex]]/PageAddListing1.tsx
  22. 50
      src/app/add-listing/[[...stepIndex]]/layout.tsx
  23. 126
      src/app/add-listing/[[...stepIndex]]/page.tsx
  24. 227
      src/app/add-new-passenger/page.tsx
  25. 26
      src/app/api/hello/auth/[...nextauth].ts
  26. 3
      src/app/api/hello/route.ts
  27. 151
      src/app/forgot-password/page.tsx
  28. 5
      src/app/globals.css
  29. 21
      src/app/layout.tsx
  30. 170
      src/app/login/page.tsx
  31. 55
      src/app/page.tsx
  32. 150
      src/app/signup/methodes/page.tsx
  33. 132
      src/app/signup/otp-code/page.tsx
  34. 191
      src/app/signup/page.tsx
  35. 94
      src/app/tours/[slug]/GuestsInput.tsx
  36. 69
      src/app/tours/[slug]/StayDatesRangeInput.tsx
  37. 71
      src/app/tours/[slug]/constant.ts
  38. 648
      src/app/tours/[slug]/page.tsx
  39. 70
      src/app/tours/layout.tsx
  40. 9
      src/components/CardCategory3.tsx
  41. 27
      src/components/HeaderFilter.tsx
  42. 69
      src/components/SectionCustomTour.tsx
  43. 73
      src/components/SectionGridFeaturePlaces.tsx
  44. 55
      src/components/SectionSliderNewCategories.tsx
  45. 54
      src/components/StayCard2.tsx
  46. 31
      src/components/api/axios.tsx
  47. 36
      src/components/api/getImageURL.tsx
  48. 73
      src/components/contexts/tourDetails.tsx
  49. 26
      src/components/contexts/userContext.tsx
  50. 21
      src/data/jsons/__stayListing.json
  51. 368
      src/data/navigation.ts
  52. 49
      src/hooks/FormValidation.ts
  53. BIN
      src/images/hero-right-orginal.png
  54. BIN
      src/images/hero-right.png
  55. BIN
      src/images/logos/لوگو3 1.png
  56. 11
      src/images/logos/لوگو3 1.svg
  57. 38
      src/shared/Avatar.tsx
  58. 65
      src/shared/Badge.tsx
  59. 2
      src/shared/ButtonPrimary.tsx
  60. 1
      src/shared/Input.tsx
  61. 23
      src/shared/Logo.tsx
  62. 2
      src/shared/LogoSvgLight.tsx
  63. 3
      src/shared/Navigation/Navigation.tsx
  64. 0
      src/shared/PhoneNumberInput.tsx
  65. 3
      tailwind.config.js
  66. 82
      yarn.lock

4
.env.local.example

@ -1,4 +0,0 @@
NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME=dwi7o19nn
CLOUDINARY_API_KEY=549144472596919
CLOUDINARY_API_SECRET=AnNiPOszr1R0YCelomUmi9IyuBM
CLOUDINARY_FOLDER=test

10
next.config.js

@ -1,10 +1,6 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: false,
experimental: {
appDir: true,
typedRoutes: true,
},
images: {
remotePatterns: [
{
@ -31,6 +27,12 @@ const nextConfig = {
port: "",
pathname: "/**",
},
{
protocol: "https",
hostname: "aqila.nwhco.ir",
port: "",
pathname: "/**",
},
],
},
};

358
package-lock.json

@ -18,6 +18,7 @@
"@types/react": "18.2.7",
"@types/react-datepicker": "^4.11.2",
"@types/react-dom": "18.2.4",
"axios": "^1.7.5",
"client-only": "^0.0.1",
"eslint": "8.41.0",
"eslint-config-next": "^13.4.3",
@ -25,12 +26,13 @@
"google-map-react": "^2.2.1",
"lodash": "^4.17.21",
"next": "^13.4.3",
"next-auth": "^4.23.1",
"next-auth": "^4.24.7",
"rc-slider": "^10.1.1",
"react": "^18.2.0",
"react-datepicker": "^4.11.0",
"react-dom": "^18.2.0",
"react-hooks-global-state": "^2.1.0",
"react-icons": "^5.3.0",
"react-swipeable": "^7.0.0",
"react-use": "^17.4.0",
"react-use-keypress": "^1.3.1",
@ -303,6 +305,126 @@
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/@next/swc-darwin-arm64": {
"version": "13.4.3",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.4.3.tgz",
"integrity": "sha512-yx18udH/ZmR4Bw4M6lIIPE3JxsAZwo04iaucEfA2GMt1unXr2iodHUX/LAKNyi6xoLP2ghi0E+Xi1f4Qb8f1LQ==",
"cpu": [
"arm64"
],
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@next/swc-darwin-x64": {
"version": "13.4.3",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.4.3.tgz",
"integrity": "sha512-Mi8xJWh2IOjryAM1mx18vwmal9eokJ2njY4nDh04scy37F0LEGJ/diL6JL6kTXi0UfUCGbMsOItf7vpReNiD2A==",
"cpu": [
"x64"
],
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@next/swc-linux-arm64-gnu": {
"version": "13.4.3",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.4.3.tgz",
"integrity": "sha512-aBvtry4bxJ1xwKZ/LVPeBGBwWVwxa4bTnNkRRw6YffJnn/f4Tv4EGDPaVeYHZGQVA56wsGbtA6nZMuWs/EIk4Q==",
"cpu": [
"arm64"
],
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@next/swc-linux-arm64-musl": {
"version": "13.4.3",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.4.3.tgz",
"integrity": "sha512-krT+2G3kEsEUvZoYte3/2IscscDraYPc2B+fDJFipPktJmrv088Pei/RjrhWm5TMIy5URYjZUoDZdh5k940Dyw==",
"cpu": [
"arm64"
],
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@next/swc-linux-x64-gnu": {
"version": "13.4.3",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.4.3.tgz",
"integrity": "sha512-AMdFX6EKJjC0G/CM6hJvkY8wUjCcbdj3Qg7uAQJ7PVejRWaVt0sDTMavbRfgMchx8h8KsAudUCtdFkG9hlEClw==",
"cpu": [
"x64"
],
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@next/swc-linux-x64-musl": {
"version": "13.4.3",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.4.3.tgz",
"integrity": "sha512-jySgSXE48shaLtcQbiFO9ajE9mqz7pcAVLnVLvRIlUHyQYR/WyZdK8ehLs65Mz6j9cLrJM+YdmdJPyV4WDaz2g==",
"cpu": [
"x64"
],
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@next/swc-win32-arm64-msvc": {
"version": "13.4.3",
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.4.3.tgz",
"integrity": "sha512-5DxHo8uYcaADiE9pHrg8o28VMt/1kR8voDehmfs9AqS0qSClxAAl+CchjdboUvbCjdNWL1MISCvEfKY2InJ3JA==",
"cpu": [
"arm64"
],
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@next/swc-win32-ia32-msvc": {
"version": "13.4.3",
"resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.4.3.tgz",
"integrity": "sha512-LaqkF3d+GXRA5X6zrUjQUrXm2MN/3E2arXBtn5C7avBCNYfm9G3Xc646AmmmpN3DJZVaMYliMyCIQCMDEzk80w==",
"cpu": [
"ia32"
],
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@next/swc-win32-x64-msvc": {
"version": "13.4.3",
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.4.3.tgz",
@ -875,6 +997,11 @@
"integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==",
"license": "ISC"
},
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
"node_modules/autoprefixer": {
"version": "10.4.14",
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz",
@ -930,6 +1057,16 @@
"node": ">=4"
}
},
"node_modules/axios": {
"version": "1.7.5",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.5.tgz",
"integrity": "sha512-fZu86yCo+svH3uqJ/yTdQ0QHpQu5oL+/QE+QPSv6BZSkDAoky9vytxp7u5qk83OJFS3kEBcesWni9WTZAv3tSw==",
"dependencies": {
"follow-redirects": "^1.15.6",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
}
},
"node_modules/axobject-query": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.1.1.tgz",
@ -1176,6 +1313,17 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"license": "MIT"
},
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"dependencies": {
"delayed-stream": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/commander": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
@ -1398,6 +1546,14 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/didyoumean": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
@ -2156,6 +2312,25 @@
"integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
"license": "ISC"
},
"node_modules/follow-redirects": {
"version": "1.15.6",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
"integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
"engines": {
"node": ">=4.0"
},
"peerDependenciesMeta": {
"debug": {
"optional": true
}
}
},
"node_modules/for-each": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
@ -2165,6 +2340,19 @@
"is-callable": "^1.1.3"
}
},
"node_modules/form-data": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/fraction.js": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz",
@ -2992,9 +3180,9 @@
}
},
"node_modules/jose": {
"version": "4.14.6",
"resolved": "https://registry.npmjs.org/jose/-/jose-4.14.6.tgz",
"integrity": "sha512-EqJPEUlZD0/CSUMubKtMaYUOtWe91tZXTWMJZoKSbLk+KtdhNdcvppH8lA9XwVu2V4Ailvsj0GBZJ2ZwDjfesQ==",
"version": "4.15.9",
"resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz",
"integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==",
"funding": {
"url": "https://github.com/sponsors/panva"
}
@ -3200,6 +3388,25 @@
"node": ">=8.6"
}
},
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime-types": {
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"dependencies": {
"mime-db": "1.52.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mimic-fn": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz",
@ -3358,14 +3565,14 @@
}
},
"node_modules/next-auth": {
"version": "4.23.1",
"resolved": "https://registry.npmjs.org/next-auth/-/next-auth-4.23.1.tgz",
"integrity": "sha512-mL083z8KgRtlrIV6CDca2H1kduWJuK/3pTS0Fe2og15KOm4v2kkLGdSDfc2g+019aEBrJUT0pPW2Xx42ImN1WA==",
"version": "4.24.7",
"resolved": "https://registry.npmjs.org/next-auth/-/next-auth-4.24.7.tgz",
"integrity": "sha512-iChjE8ov/1K/z98gdKbn2Jw+2vLgJtVV39X+rCP5SGnVQuco7QOr19FRNGMIrD8d3LYhHWV9j9sKLzq1aDWWQQ==",
"dependencies": {
"@babel/runtime": "^7.20.13",
"@panva/hkdf": "^1.0.2",
"cookie": "^0.5.0",
"jose": "^4.11.4",
"jose": "^4.15.5",
"oauth": "^0.9.15",
"openid-client": "^5.4.0",
"preact": "^10.6.3",
@ -3373,7 +3580,7 @@
"uuid": "^8.3.2"
},
"peerDependencies": {
"next": "^12.2.5 || ^13",
"next": "^12.2.5 || ^13 || ^14",
"nodemailer": "^6.6.5",
"react": "^17.0.2 || ^18",
"react-dom": "^17.0.2 || ^18"
@ -3982,6 +4189,11 @@
"react-is": "^16.13.1"
}
},
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
},
"node_modules/punycode": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
@ -4104,6 +4316,14 @@
"react": ">=16.8.0"
}
},
"node_modules/react-icons": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.3.0.tgz",
"integrity": "sha512-DnUk8aFbTyQPSkCfF8dbX6kQjXA9DktMeJqfjrg6cK9vwQVMxmcA3BfP4QoiztVmEHtwlTgLFsPuH2NskKT6eg==",
"peerDependencies": {
"react": "*"
}
},
"node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
@ -5340,126 +5560,6 @@
"optional": true
}
}
},
"node_modules/@next/swc-darwin-arm64": {
"version": "13.4.3",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.4.3.tgz",
"integrity": "sha512-yx18udH/ZmR4Bw4M6lIIPE3JxsAZwo04iaucEfA2GMt1unXr2iodHUX/LAKNyi6xoLP2ghi0E+Xi1f4Qb8f1LQ==",
"cpu": [
"arm64"
],
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@next/swc-darwin-x64": {
"version": "13.4.3",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.4.3.tgz",
"integrity": "sha512-Mi8xJWh2IOjryAM1mx18vwmal9eokJ2njY4nDh04scy37F0LEGJ/diL6JL6kTXi0UfUCGbMsOItf7vpReNiD2A==",
"cpu": [
"x64"
],
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@next/swc-linux-arm64-gnu": {
"version": "13.4.3",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.4.3.tgz",
"integrity": "sha512-aBvtry4bxJ1xwKZ/LVPeBGBwWVwxa4bTnNkRRw6YffJnn/f4Tv4EGDPaVeYHZGQVA56wsGbtA6nZMuWs/EIk4Q==",
"cpu": [
"arm64"
],
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@next/swc-linux-arm64-musl": {
"version": "13.4.3",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.4.3.tgz",
"integrity": "sha512-krT+2G3kEsEUvZoYte3/2IscscDraYPc2B+fDJFipPktJmrv088Pei/RjrhWm5TMIy5URYjZUoDZdh5k940Dyw==",
"cpu": [
"arm64"
],
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@next/swc-linux-x64-gnu": {
"version": "13.4.3",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.4.3.tgz",
"integrity": "sha512-AMdFX6EKJjC0G/CM6hJvkY8wUjCcbdj3Qg7uAQJ7PVejRWaVt0sDTMavbRfgMchx8h8KsAudUCtdFkG9hlEClw==",
"cpu": [
"x64"
],
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@next/swc-linux-x64-musl": {
"version": "13.4.3",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.4.3.tgz",
"integrity": "sha512-jySgSXE48shaLtcQbiFO9ajE9mqz7pcAVLnVLvRIlUHyQYR/WyZdK8ehLs65Mz6j9cLrJM+YdmdJPyV4WDaz2g==",
"cpu": [
"x64"
],
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@next/swc-win32-arm64-msvc": {
"version": "13.4.3",
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.4.3.tgz",
"integrity": "sha512-5DxHo8uYcaADiE9pHrg8o28VMt/1kR8voDehmfs9AqS0qSClxAAl+CchjdboUvbCjdNWL1MISCvEfKY2InJ3JA==",
"cpu": [
"arm64"
],
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@next/swc-win32-ia32-msvc": {
"version": "13.4.3",
"resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.4.3.tgz",
"integrity": "sha512-LaqkF3d+GXRA5X6zrUjQUrXm2MN/3E2arXBtn5C7avBCNYfm9G3Xc646AmmmpN3DJZVaMYliMyCIQCMDEzk80w==",
"cpu": [
"ia32"
],
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 10"
}
}
}
}

4
package.json

@ -19,6 +19,7 @@
"@types/react": "18.2.7",
"@types/react-datepicker": "^4.11.2",
"@types/react-dom": "18.2.4",
"axios": "^1.7.5",
"client-only": "^0.0.1",
"eslint": "8.41.0",
"eslint-config-next": "^13.4.3",
@ -26,12 +27,13 @@
"google-map-react": "^2.2.1",
"lodash": "^4.17.21",
"next": "^13.4.3",
"next-auth": "^4.23.1",
"next-auth": "^4.24.7",
"rc-slider": "^10.1.1",
"react": "^18.2.0",
"react-datepicker": "^4.11.0",
"react-dom": "^18.2.0",
"react-hooks-global-state": "^2.1.0",
"react-icons": "^5.3.0",
"react-swipeable": "^7.0.0",
"react-use": "^17.4.0",
"react-use-keypress": "^1.3.1",

11
public/لوگو3 1.svg
File diff suppressed because it is too large
View File

2
src/app/(account-pages)/(components)/Nav.tsx

@ -12,7 +12,7 @@ export const Nav = () => {
"/account",
"/account-savelists",
"/account-password",
"/account-billing",
"/passengers-list",
];
return (

32
src/app/(account-pages)/account-billing/page.tsx

@ -1,32 +0,0 @@
import React from "react";
import ButtonPrimary from "@/shared/ButtonPrimary";
const AccountBilling = () => {
return (
<div className="space-y-6 sm:space-y-8">
{/* HEADING */}
<h2 className="text-3xl font-semibold">Payments & payouts</h2>
<div className="w-14 border-b border-neutral-200 dark:border-neutral-700"></div>
<div className="max-w-2xl">
<span className="text-xl font-semibold block">Payout methods</span>
<br />
<span className="text-neutral-700 dark:text-neutral-300 block">
{` When you receive a payment for a reservation, we call that payment
to you a "payout." Our secure payment system supports several
payout methods, which can be set up below. Go to FAQ.`}
<br />
<br />
To get paid, you need to set up a payout method Airbnb releases
payouts about 24 hours after a guests scheduled check-in time. The
time it takes for the funds to appear in your account depends on your
payout method. Learn more
</span>
<div className="pt-10">
<ButtonPrimary>Add payout mothod</ButtonPrimary>
</div>
</div>
</div>
);
};
export default AccountBilling;

196
src/app/(account-pages)/account/page.tsx

@ -1,23 +1,131 @@
import React, { FC } from "react";
"use client";
import React, { useContext, useState } from "react";
import Label from "@/components/Label";
import Avatar from "@/shared/Avatar";
import ButtonPrimary from "@/shared/ButtonPrimary";
import Input from "@/shared/Input";
import Select from "@/shared/Select";
import Textarea from "@/shared/Textarea";
import ButtonSecondary from "@/shared/ButtonSecondary";
import axiosInstance from "@/components/api/axios";
import { useRouter } from "next/navigation";
import { user as UserContext } from "@/components/contexts/userContext";
import getImageURL from "@/components/api/getImageURL";
export interface AccountPageProps {}
const AccountPage = () => {
const router = useRouter();
const User = JSON.parse(localStorage.getItem("user"))
let user = JSON.parse(localStorage.getItem("user"));
if (!user) {
return router.replace("/");
}
const { setStatus } = useContext(UserContext);
const [name, setName] = useState(user.fullname || "");
const [email, setEmail] = useState(user.email || "");
const [number, setNumber] = useState(user.phone_number || "");
const [password, setPassword] = useState("");
const [image, setImage] = useState<File | null>(null);
const [imageURL, setImageURL] = useState<string | null>(null);
const [error, setError] = useState("");
const deleteHandler = async () => {
setStatus(false);
setError("");
try {
const response = await axiosInstance.delete(
`/api/account/profile/delete/`,
{
headers: {
Authorization: `token ${user.token}`,
},
}
);
if (response.status === 204) {
localStorage.removeItem("user");
router.replace("/");
} else {
setError("Something went wrong");
}
} catch (error) {
setError(error.message);
}
};
const signOutHandler = () => {
localStorage.removeItem("user");
setStatus(false);
router.replace("/");
};
const changeHandler = async () => {
setError("");
const formData = new FormData();
formData.append("fullname", name);
formData.append("email", email);
formData.append("password", password);
if (imageURL) {
formData.append("avatar", imageURL);
}
try {
const response = await axiosInstance.put(
`/api/account/profile/update/`,
formData,
{
headers: {
Authorization: `token ${user.token}`,
"Content-Type": "multipart/form-data",
},
}
);
if (response.status === 200) {
console.log(response);
user.avatar = response.data.avatar;
user.email = response.data.email;
user.fullname = response.data.fullname;
user.phone_number = response.data.phone_number;
localStorage.setItem("user", JSON.stringify(user));
} else {
setError("Something went wrong");
}
} catch (error) {
setError(error.message);
}
};
const handleFileChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
const file = e.target.files?.[0];
if (file) {
const uploadedFile = await getImageURL(file);
setImageURL(uploadedFile.url);
};
setImage(file);
}
return (
<div className="space-y-6 sm:space-y-8">
{/* HEADING */}
<h2 className="text-3xl font-semibold">Account infomation</h2>
<h2 className="text-3xl font-semibold">Account information</h2>
<div className="w-14 border-b border-neutral-200 dark:border-neutral-700"></div>
<div className="flex flex-col md:flex-row">
<div className="flex-shrink-0 flex items-start">
<div className="relative rounded-full overflow-hidden flex">
<Avatar sizeClass="w-32 h-32" />
<Avatar
imgUrl={
imageURL || (image ? URL.createObjectURL(image) : User.avatar)
}
sizeClass="w-32 h-32"
/>
<div className="absolute inset-0 bg-black bg-opacity-60 flex flex-col items-center justify-center text-neutral-50 cursor-pointer">
<svg
width="30"
@ -40,55 +148,61 @@ const AccountPage = () => {
<input
type="file"
className="absolute inset-0 opacity-0 cursor-pointer"
onChange={handleFileChange}
accept="image/*"
/>
</div>
</div>
<div className="flex-grow mt-10 md:mt-0 md:pl-16 max-w-3xl space-y-6">
<div>
<Label>Name</Label>
<Input className="mt-1.5" defaultValue="Eden Tuan" />
</div>
{/* ---- */}
<div>
<Label>Gender</Label>
<Select className="mt-1.5">
<option value="Male">Male</option>
<option value="Female">Female</option>
<option value="Other">Other</option>
</Select>
</div>
{/* ---- */}
<div>
<Label>Username</Label>
<Input className="mt-1.5" defaultValue="@eden_tuan" />
<Input
value={name}
onChange={(e) => setName(e.target.value)}
className="mt-1.5"
/>
</div>
{/* ---- */}
<div>
<Label>Email</Label>
<Input className="mt-1.5" defaultValue="example@email.com" />
<Input
value={email}
onChange={(e) => setEmail(e.target.value)}
className="mt-1.5"
/>
</div>
{/* ---- */}
<div className="max-w-lg">
<Label>Date of birth</Label>
<Input className="mt-1.5" type="date" defaultValue="1990-07-22" />
</div>
{/* ---- */}
<div>
<Label>Addess</Label>
<Input className="mt-1.5" defaultValue="New york, USA" />
</div>
{/* ---- */}
<div>
<Label>Phone number</Label>
<Input className="mt-1.5" defaultValue="003 888 232" />
<Label>Phone</Label>
<Input
value={number}
onChange={(e) => setNumber(e.target.value)}
className="[appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none mt-1.5"
type="text"
/>
</div>
{/* ---- */}
<div>
<Label>About you</Label>
<Textarea className="mt-1.5" defaultValue="..." />
<Label>Password</Label>
<Input
value={password}
onChange={(e) => setPassword(e.target.value)}
type="password"
className="mt-1.5"
/>
</div>
<div className="pt-2">
<ButtonPrimary>Update info</ButtonPrimary>
{error && <p className=" text-red-500 text-xs">{error}</p>}
<div className=" flex flex-col pt-2 sm:flex-row ">
<ButtonPrimary className="mt-8" onClick={changeHandler}>
Update info
</ButtonPrimary>
<ButtonPrimary className="mt-8 sm:ml-8 " onClick={signOutHandler}>
{" "}
Sign out
</ButtonPrimary>
<ButtonSecondary
onClick={deleteHandler}
className="opacity-60 mt-8 hover:bg-red-500 hover:text-white hover:opacity-100 sm:ml-8"
>
Delete account
</ButtonSecondary>
</div>
</div>
</div>

55
src/app/(account-pages)/passengers-list/PassengerTable.tsx

@ -0,0 +1,55 @@
import axiosInstance from "@/components/api/axios";
import React, { useState } from "react";
import { IoMdTrash } from "react-icons/io";
import { MdEdit } from "react-icons/md";
const PassengerTable = ({data}) => {
const user = JSON.parse(localStorage.getItem("user"))
const [show , setShow] =useState(true)
const deletHandler = async ()=>{
try{
const response = await axiosInstance.delete(`/api/account/passengers/${data.id}/` ,{
headers :{
Authorization : `token ${user.token}`
}
})
console.log(response);
setShow(false)
}catch (error){
console.log(error);
}
}
return (
<div className= {`${!show && "hidden" } sm:w-[500px] flex items-center justify-between p-4 bg-white rounded-xl shadow-sm border border-neutral-200 dark:bg-neutral-800`}>
{/* Passenger Information */}
<div className="flex flex-col">
<p className="text-sm text-neutral-500 dark:text-neutral-400">
Passenger information
</p>
<h3 className="text-lg font-semibold text-neutral-900 dark:text-white">
{data.fullname}
</h3>
</div>
{/* Action Icons */}
<div className="flex space-x-6 text-neutral-500">
<button className="hover:text-red-500 transition-colors">
<button type="submit">
<IoMdTrash onClick={deletHandler} className="text-2xl" /> {/* Increased size using text-2xl */}
</button>
</button>
<button className="hover:text-blue-500 transition-colors">
<MdEdit className="text-2xl" /> {/* Increased size using text-2xl */}
</button>
</div>
</div>
);
};
export default PassengerTable;

52
src/app/(account-pages)/passengers-list/page.tsx

@ -0,0 +1,52 @@
"use client"
import React, { useEffect, useState } from "react";
import PassengerTable from "./PassengerTable";
import { IoPersonAddOutline } from "react-icons/io5";
import axiosInstance from "@/components/api/axios";
import Link from "next/link";
const PassengersList = () => {
const user = JSON.parse(localStorage.getItem("user"))
const [passengers , setPassenger ] = useState([])
useEffect(()=>{
axiosInstance.get("/api/account/passengers/" ,{
headers :{
Authorization : `token ${user.token}`
}
})
.then((response)=>{
setPassenger(response.data.results);
console.log(response);
}).catch((error)=>{
console.error(error);
})
console.log(passengers);
} , [])
return (
<div className="flex flex-col items-start space-y-6 sm:space-y-8">
{/* Add New Passenger Section */}
<Link href={"/add-new-passenger"} className="flex items-center space-x-2 text-orange-500 cursor-pointer hover:text-orange-600">
<IoPersonAddOutline className="text-xl" /> {/* Adjust icon size */}
<p className="text-sm font-medium">Add new passenger</p>
</Link>
{/* Passenger Table */}
{passengers.map((item)=>(
<PassengerTable key={item.id} data={item} />
))}
</div>
);
};
export default PassengersList;

22
src/app/(client-components)/(Header)/Header.tsx

@ -8,22 +8,22 @@ export interface HeaderProps {
}
const Header: FC<HeaderProps> = ({ navType = "MainNav1", className = "" }) => {
const renderNav = () => {
switch (navType) {
case "MainNav1":
return <MainNav1 />;
case "MainNav2":
return <MainNav2 />;
default:
return <MainNav1 />;
}
};
// const renderNav = () => {
// switch (navType) {
// case "MainNav1":
// return <MainNav1 />;
// case "MainNav2":
// return <MainNav2 />;
// default:
// return <MainNav1 />;
// }
// };
return (
<div
className={`nc-Header sticky top-0 w-full left-0 right-0 z-40 nc-header-bg ${className}`}
>
{renderNav()}
<MainNav1 />
</div>
);
};

42
src/app/(client-components)/(Header)/MainNav1.tsx

@ -1,4 +1,4 @@
import React, { FC } from "react";
import React, { FC, useContext, useEffect, useState } from "react";
import Logo from "@/shared/Logo";
import Navigation from "@/shared/Navigation/Navigation";
import SearchDropdown from "./SearchDropdown";
@ -6,13 +6,27 @@ import ButtonPrimary from "@/shared/ButtonPrimary";
import MenuBar from "@/shared/MenuBar";
import SwitchDarkMode from "@/shared/SwitchDarkMode";
import HeroSearchForm2MobileFactory from "../(HeroSearchForm2Mobile)/HeroSearchForm2MobileFactory";
import LangDropdown from "./LangDropdown";
import { MdOutlineLanguage } from "react-icons/md";
import Avatar from "@/shared/Avatar";
import Link from "next/link";
import { user } from "@/components/contexts/userContext";
export interface MainNav1Props {
className?: string;
}
const MainNav1: FC<MainNav1Props> = ({ className = "" }) => {
const { status, setStatus } = useContext(user);
const User = JSON.parse(localStorage.getItem("user"))
User? setStatus(true) : setStatus(false)
console.log(status);
console.log(User.avatar);
return (
<div className={`nc-MainNav1 relative z-10 ${className}`}>
<div className="px-4 lg:container h-20 relative flex justify-between">
@ -21,23 +35,37 @@ const MainNav1: FC<MainNav1Props> = ({ className = "" }) => {
<Navigation />
</div>
<div className="flex lg:hidden flex-[3] max-w-lg !mx-auto md:px-3 ">
<div className="flex lg:hidden flex-[3] max-w-lg !mx-auto md:px-3">
<div className="self-center flex-1">
<HeroSearchForm2MobileFactory />
</div>
</div>
<div className="hidden md:flex flex-shrink-0 justify-end flex-1 lg:flex-none text-neutral-700 dark:text-neutral-100">
<div className="hidden xl:flex space-x-0.5">
<div className="hidden xl:flex space-x-0.5 items-center">
<div className="cursor-pointer self-center text-2xl md:text-[28px] w-12 h-12 rounded-full text-neutral-700 dark:text-neutral-300 hover:bg-neutral-100 dark:hover:bg-neutral-800 focus:outline-none flex items-center justify-center">
<MdOutlineLanguage size={25} />
</div>
<SwitchDarkMode />
<SearchDropdown className="flex items-center" />
<div className="px-1" />
<ButtonPrimary className="self-center" href="/login">
Sign up
</ButtonPrimary>
{status ? (<Link href={"/account"}>
<Avatar
imgUrl={User.avatar}
sizeClass="w-10 h-10"
/>
</Link>
) : (
<ButtonPrimary className="self-center" href="/signup">
Sign up
</ButtonPrimary>
)}
</div>
<div className="flex xl:hidden items-center">
<div className="cursor-pointer self-center text-2xl md:text-[28px] w-12 h-12 rounded-full text-neutral-700 dark:text-neutral-300 hover:bg-neutral-100 dark:hover:bg-neutral-800 focus:outline-none flex items-center justify-center">
<MdOutlineLanguage size={25} />
</div>
<SwitchDarkMode />
<div className="px-0.5" />
<MenuBar />

13
src/app/(client-components)/(Header)/SiteHeader.tsx

@ -34,7 +34,7 @@ const PAGES_HIDE_HEADER_BORDER: PathName[] = [
];
const SiteHeader = () => {
const anchorRef = useRef<HTMLDivElement>(null);
{/* const anchorRef = useRef<HTMLDivElement>(null);
let [headers] = useState<SiteHeaders[]>(["Header 1", "Header 2", "Header 3"]);
@ -91,7 +91,7 @@ const SiteHeader = () => {
}`}
onClick={() => setHeaderSelected(header)}
>
{header}
{headers[0]}
</div>
);
})}
@ -187,13 +187,14 @@ const SiteHeader = () => {
default:
return <Header className={headerClassName} navType="MainNav1" />;
}
};
};*/}
return (
<>
{renderControlSelections()}
{renderHeader()}
<div ref={anchorRef} className="h-1 absolute invisible"></div>
<Header className="shadow-sm dark:border-b dark:border-neutral-700" navType="MainNav1" />
{/* {renderControlSelections()}
{renderHeader()}*/}
{/* <div ref={anchorRef} className="h-1 absolute invisible"></div>*/}
</>
);
};

95
src/app/(client-components)/(HeroSearchForm)/(stay-search-form)/StayDatesRangeInput.tsx

@ -1,12 +1,13 @@
"use client";
import React, { Fragment, useState, FC } from "react";
import React, { Fragment, useState, FC, useContext } from "react";
import { Popover, Transition } from "@headlessui/react";
import { CalendarIcon } from "@heroicons/react/24/outline";
import DatePickerCustomHeaderTwoMonth from "@/components/DatePickerCustomHeaderTwoMonth";
import DatePickerCustomDay from "@/components/DatePickerCustomDay";
import DatePicker from "react-datepicker";
import ClearDataButton from "../ClearDataButton";
import { Context } from "@/components/contexts/tourDetails";
export interface StayDatesRangeInputProps {
className?: string;
@ -17,11 +18,9 @@ const StayDatesRangeInput: FC<StayDatesRangeInputProps> = ({
className = "[ lg:nc-flex-2 ]",
fieldClassName = "[ nc-hero-field-padding ]",
}) => {
const [startDate, setStartDate] = useState<Date | null>(
new Date("2023/02/06")
);
const [endDate, setEndDate] = useState<Date | null>(new Date("2023/02/23"));
//
const { details} = useContext(Context);
const onChangeDate = (dates: [Date | null, Date | null]) => {
const [start, end] = dates;
@ -29,54 +28,58 @@ const StayDatesRangeInput: FC<StayDatesRangeInputProps> = ({
setEndDate(end);
};
const renderInput = () => {
return (
<>
<div className="text-neutral-300 dark:text-neutral-400">
<CalendarIcon className="w-5 h-5 lg:w-7 lg:h-7" />
</div>
<div className="flex-grow text-left">
<span className="block xl:text-lg font-semibold">
{startDate?.toLocaleDateString("en-US", {
month: "short",
day: "2-digit",
}) || "Add dates"}
{endDate
? " - " +
endDate?.toLocaleDateString("en-US", {
month: "short",
day: "2-digit",
})
: ""}
</span>
<span className="block mt-1 text-sm text-neutral-400 leading-none font-light">
{"Check in - Check out"}
</span>
</div>
</>
);
};
// const renderInput = () => {
// return (
// <>
// <div className="text-neutral-300 dark:text-neutral-400">
// <CalendarIcon className="w-5 h-5 lg:w-7 lg:h-7" />
// </div>
// <div className="flex-grow text-left">
// <span className="block xl:text-lg font-semibold">
// {startDate ? startDate.toLocaleDateString("en-US", {
// month: "short",
// day: "2-digit",
// }) : "Tour period"}
// {" - " +
// endDate?.toLocaleDateString("en-US", {
// month: "short",
// day: "2-digit",
// }) || ""}
// </span>
// <span className="block mt-1 text-sm text-neutral-400 leading-none font-light">
// {"Start - End"}
// </span>
// </div>
// </>
// );
// };
return (
<Popover className={`StayDatesRangeInput z-10 relative flex ${className}`}>
{({ open }) => (
<>
<Popover.Button
className={`flex-1 z-10 flex relative ${fieldClassName} items-center space-x-3 focus:outline-none ${
open ? "nc-hero-field-focused" : ""
}`}
<div
className={`flex-1 z-10 flex relative ${fieldClassName} items-center space-x-3 focus:outline-none`}
>
{renderInput()}
{startDate && open && (
<ClearDataButton onClick={() => onChangeDate([null, null])} />
)}
</Popover.Button>
<div className="text-neutral-300 dark:text-neutral-400">
<CalendarIcon className="w-5 h-5 lg:w-7 lg:h-7" />
</div>
<div className="flex-grow text-left">
<span className="block xl:text-lg font-semibold">
{details?.started_at.replaceAll("-", "/") || "Tour period"}
{details?.ended_at && " - " + details?.ended_at.replaceAll("-", "/")}
</span>
<span className="block mt-1 text-sm text-neutral-400 leading-none font-light">
{"Start - End"}
</span>
</div>
</div>
{open && (
{/* {open && (
<div className="h-8 absolute self-center top-1/2 -translate-y-1/2 z-0 -inset-x-0.5 bg-white dark:bg-neutral-800"></div>
)}
)} */}
<Transition
{/* <Transition
as={Fragment}
enter="transition ease-out duration-200"
enterFrom="opacity-0 translate-y-1"
@ -105,7 +108,7 @@ const StayDatesRangeInput: FC<StayDatesRangeInputProps> = ({
/>
</div>
</Popover.Panel>
</Transition>
</Transition> */}
</>
)}
</Popover>

2
src/app/(client-components)/(HeroSearchForm)/ButtonSubmit.tsx

@ -11,7 +11,7 @@ const ButtonSubmit: FC<Props> = ({ href = "/listing-stay-map" }) => {
<Link
href={href}
type="button"
className="h-14 md:h-16 w-full md:w-16 rounded-full bg-primary-6000 hover:bg-primary-700 flex items-center justify-center text-neutral-50 focus:outline-none"
className="h-14 md:h-16 w-full md:w-16 rounded-full bg-bronze hover:bg-bronze-secondary flex items-center justify-center text-neutral-50 hover:text-bronze focus:outline-none"
>
<span className="mr-3 md:hidden">Search</span>
<svg

62
src/app/(client-components)/(HeroSearchForm)/GuestsInput.tsx

@ -1,6 +1,7 @@
"use client";
import React, { Fragment, useEffect, useState } from "react";
"use client"
import React, { Fragment, useContext, useEffect, useState } from "react";
import { Popover, Transition } from "@headlessui/react";
import NcInputNumber from "@/components/NcInputNumber";
import { FC } from "react";
@ -9,6 +10,7 @@ import ButtonSubmit from "./ButtonSubmit";
import { PathName } from "@/routers/types";
import { UserPlusIcon } from "@heroicons/react/24/outline";
import { GuestsObject } from "../type";
import { Context } from "@/components/contexts/tourDetails";
export interface GuestsInputProps {
fieldClassName?: string;
@ -24,31 +26,23 @@ const GuestsInput: FC<GuestsInputProps> = ({
hasButtonSubmit = true,
}) => {
const [guestAdultsInputValue, setGuestAdultsInputValue] = useState(2);
const [guestChildrenInputValue, setGuestChildrenInputValue] = useState(1);
const [guestInfantsInputValue, setGuestInfantsInputValue] = useState(1);
const { passengers, details , setPassengers } = useContext(Context);
const handleChangeData = (value: number, type: keyof GuestsObject) => {
let newValue = {
guestAdults: guestAdultsInputValue,
guestChildren: guestChildrenInputValue,
guestInfants: guestInfantsInputValue,
};
if (type === "guestAdults") {
setGuestAdultsInputValue(value);
newValue.guestAdults = value;
}
if (type === "guestChildren") {
setGuestChildrenInputValue(value);
newValue.guestChildren = value;
}
if (type === "guestInfants") {
setGuestInfantsInputValue(value);
newValue.guestInfants = value;
}
setGuestAdultsInputValue(value);
newValue.guestAdults = value;
setPassengers(value)
};
const totalGuests =
guestChildrenInputValue + guestAdultsInputValue + guestInfantsInputValue;
useEffect(()=>{
setPassengers(guestAdultsInputValue)
} , [])
console.log(passengers);
return (
<Popover className={`flex relative ${className}`}>
@ -67,19 +61,18 @@ const GuestsInput: FC<GuestsInputProps> = ({
</div>
<div className="flex-grow">
<span className="block xl:text-lg font-semibold">
{totalGuests || ""} Guests
{guestAdultsInputValue || ""} Passengers
</span>
<span className="block mt-1 text-sm text-neutral-400 leading-none font-light">
{totalGuests ? "Guests" : "Add guests"}
{guestAdultsInputValue ? "Passengers" : "Add passengers"}
</span>
</div>
{!!totalGuests && open && (
{!!guestAdultsInputValue && open && (
<ClearDataButton
onClick={() => {
setGuestAdultsInputValue(0);
setGuestChildrenInputValue(0);
setGuestInfantsInputValue(0);
setPassengers(0)
}}
/>
)}
@ -88,7 +81,7 @@ const GuestsInput: FC<GuestsInputProps> = ({
{/* BUTTON SUBMIT OF FORM */}
{hasButtonSubmit && (
<div className="pr-2 xl:pr-4">
<ButtonSubmit href={buttonSubmitHref} />
<ButtonSubmit href={`/tours/${details?.slug}-${details?.id}`} />
</div>
)}
</div>
@ -115,23 +108,6 @@ const GuestsInput: FC<GuestsInputProps> = ({
label="Adults"
desc="Ages 13 or above"
/>
<NcInputNumber
className="w-full mt-6"
defaultValue={guestChildrenInputValue}
onChange={(value) => handleChangeData(value, "guestChildren")}
max={4}
label="Children"
desc="Ages 2–12"
/>
<NcInputNumber
className="w-full mt-6"
defaultValue={guestInfantsInputValue}
onChange={(value) => handleChangeData(value, "guestInfants")}
max={4}
label="Infants"
desc="Ages 0–2"
/>
</Popover.Panel>
</Transition>
</>

20
src/app/(client-components)/(HeroSearchForm)/HeroSearchForm.tsx

@ -14,15 +14,15 @@ export interface HeroSearchFormProps {
currentPage?: "Stays" | "Experiences" | "Cars" | "Flights";
}
const HeroSearchForm: FC<HeroSearchFormProps> = ({
const HeroSearchForm: FC<HeroSearchFormProps> = ({/*
className = "",
currentTab = "Stays",
currentTab = "Flights",
currentPage,
}) => {
*/}) => {{/*
const tabs: SearchTab[] = ["Stays", "Experiences", "Cars", "Flights"];
const [tabActive, setTabActive] = useState<SearchTab>(currentTab);
const renderTab = () => {
{const renderTab = () => {
return (
<ul className="ml-2 sm:ml-6 md:ml-12 flex space-x-5 sm:space-x-8 lg:space-x-11 overflow-x-auto hiddenScrollbar">
{tabs.map((tab) => {
@ -46,9 +46,9 @@ const HeroSearchForm: FC<HeroSearchFormProps> = ({
})}
</ul>
);
};
};}
const renderForm = () => {
const renderForm = () => {
switch (tabActive) {
case "Stays":
return <StaySearchForm />;
@ -62,14 +62,14 @@ const HeroSearchForm: FC<HeroSearchFormProps> = ({
default:
return null;
}
};
};*/}
return (
<div
className={`nc-HeroSearchForm w-full max-w-6xl py-5 lg:py-0 ${className}`}
className={`nc-HeroSearchForm w-full max-w-6xl py-5 lg:py-0`}
>
{renderTab()}
{renderForm()}
{/*renderTab()*/}
<StaySearchForm />
</div>
);
};

70
src/app/(client-components)/(HeroSearchForm)/LocationInput.tsx

@ -1,8 +1,11 @@
"use client";
import { ClockIcon, MapPinIcon } from "@heroicons/react/24/outline";
import React, { useState, useRef, useEffect, FC } from "react";
import React, { useState, useRef, useEffect, useContext, FC } from "react";
import ClearDataButton from "./ClearDataButton";
import axiosInstance from "@/components/api/axios";
import { Context } from "@/components/contexts/tourDetails";
import { log } from "console";
export interface LocationInputProps {
placeHolder?: string;
@ -14,14 +17,15 @@ export interface LocationInputProps {
const LocationInput: FC<LocationInputProps> = ({
autoFocus = false,
placeHolder = "Location",
desc = "Where are you going?",
placeHolder = "Tours",
desc = "Select your tour",
className = "nc-flex-1.5",
divHideVerticalLineClass = "left-10 -right-0.5",
}) => {
const containerRef = useRef<HTMLDivElement>(null);
const inputRef = useRef<HTMLInputElement>(null);
const { getTourData, setPassengers, setDetails, tours } = useContext(Context);
const [value, setValue] = useState("");
const [showPopover, setShowPopover] = useState(autoFocus);
@ -56,34 +60,30 @@ const LocationInput: FC<LocationInputProps> = ({
setShowPopover