diff --git a/package-lock.json b/package-lock.json
index d40263e..ecb28ec 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,14 +8,21 @@
"name": "antalya-web",
"version": "0.1.0",
"dependencies": {
+ "axios": "^1.13.2",
+ "framer-motion": "^12.23.24",
"next": "16.0.3",
"react": "19.2.0",
- "react-dom": "19.2.0"
+ "react-dom": "19.2.0",
+ "react-google-recaptcha": "^3.1.0",
+ "selenium-webdriver": "^4.38.0",
+ "sitemap": "^9.0.0",
+ "xml2js": "^0.6.2"
},
"devDependencies": {
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",
+ "@types/react-google-recaptcha": "^2.1.9",
"eslint": "^9",
"eslint-config-next": "16.0.3",
"typescript": "^5"
@@ -261,6 +268,12 @@
"node": ">=6.9.0"
}
},
+ "node_modules/@bazel/runfiles": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/@bazel/runfiles/-/runfiles-6.5.0.tgz",
+ "integrity": "sha512-RzahvqTkfpY2jsDxo8YItPX+/iZ6hbiikw1YhE0bA9EKBR5Og8Pa6FHn9PO9M0zaXRVsr0GFQLKbB/0rzy9SzA==",
+ "license": "Apache-2.0"
+ },
"node_modules/@emnapi/core": {
"version": "1.7.1",
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.7.1.tgz",
@@ -1263,7 +1276,6 @@
"version": "20.19.25",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.25.tgz",
"integrity": "sha512-ZsJzA5thDQMSQO788d7IocwwQbI8B5OPzmqNvpf3NY/+MHDAS759Wo0gd2WQeXYt5AAAQjzcrTVC6SKCuYgoCQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"undici-types": "~6.21.0"
@@ -1289,6 +1301,25 @@
"@types/react": "^19.2.0"
}
},
+ "node_modules/@types/react-google-recaptcha": {
+ "version": "2.1.9",
+ "resolved": "https://registry.npmjs.org/@types/react-google-recaptcha/-/react-google-recaptcha-2.1.9.tgz",
+ "integrity": "sha512-nT31LrBDuoSZJN4QuwtQSF3O89FVHC4jLhM+NtKEmVF5R1e8OY0Jo4//x2Yapn2aNHguwgX5doAq8Zo+Ehd0ug==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/react": "*"
+ }
+ },
+ "node_modules/@types/sax": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz",
+ "integrity": "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "8.47.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.47.0.tgz",
@@ -1915,6 +1946,12 @@
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
+ "node_modules/arg": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
+ "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
+ "license": "MIT"
+ },
"node_modules/argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
@@ -2109,6 +2146,12 @@
"node": ">= 0.4"
}
},
+ "node_modules/asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+ "license": "MIT"
+ },
"node_modules/available-typed-arrays": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
@@ -2135,6 +2178,17 @@
"node": ">=4"
}
},
+ "node_modules/axios": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz",
+ "integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==",
+ "license": "MIT",
+ "dependencies": {
+ "follow-redirects": "^1.15.6",
+ "form-data": "^4.0.4",
+ "proxy-from-env": "^1.1.0"
+ }
+ },
"node_modules/axobject-query": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz",
@@ -2243,7 +2297,6 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
@@ -2343,6 +2396,18 @@
"dev": true,
"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==",
+ "license": "MIT",
+ "dependencies": {
+ "delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -2357,6 +2422,12 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/core-util-is": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
+ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
+ "license": "MIT"
+ },
"node_modules/cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
@@ -2501,6 +2572,15 @@
"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==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
"node_modules/detect-libc": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
@@ -2528,7 +2608,6 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
- "dev": true,
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
@@ -2626,7 +2705,6 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
@@ -2636,7 +2714,6 @@
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
@@ -2674,7 +2751,6 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0"
@@ -2687,7 +2763,6 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
@@ -3302,6 +3377,26 @@
"dev": true,
"license": "ISC"
},
+ "node_modules/follow-redirects": {
+ "version": "1.15.11",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz",
+ "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
+ },
"node_modules/for-each": {
"version": "0.3.5",
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz",
@@ -3318,11 +3413,53 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/form-data": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz",
+ "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==",
+ "license": "MIT",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "es-set-tostringtag": "^2.1.0",
+ "hasown": "^2.0.2",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/framer-motion": {
+ "version": "12.23.24",
+ "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.23.24.tgz",
+ "integrity": "sha512-HMi5HRoRCTou+3fb3h9oTLyJGBxHfW+HnNE25tAXOvVx/IvwMHK0cx7IR4a2ZU6sh3IX1Z+4ts32PcYBOqka8w==",
+ "license": "MIT",
+ "dependencies": {
+ "motion-dom": "^12.23.23",
+ "motion-utils": "^12.23.6",
+ "tslib": "^2.4.0"
+ },
+ "peerDependencies": {
+ "@emotion/is-prop-valid": "*",
+ "react": "^18.0.0 || ^19.0.0",
+ "react-dom": "^18.0.0 || ^19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@emotion/is-prop-valid": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ },
+ "react-dom": {
+ "optional": true
+ }
+ }
+ },
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
- "dev": true,
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -3383,7 +3520,6 @@
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
@@ -3408,7 +3544,6 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
- "dev": true,
"license": "MIT",
"dependencies": {
"dunder-proto": "^1.0.1",
@@ -3496,7 +3631,6 @@
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
@@ -3568,7 +3702,6 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
@@ -3581,7 +3714,6 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
- "dev": true,
"license": "MIT",
"dependencies": {
"has-symbols": "^1.0.3"
@@ -3597,7 +3729,6 @@
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"function-bind": "^1.1.2"
@@ -3623,6 +3754,15 @@
"hermes-estree": "0.25.1"
}
},
+ "node_modules/hoist-non-react-statics": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
+ "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "react-is": "^16.7.0"
+ }
+ },
"node_modules/ignore": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
@@ -3633,6 +3773,12 @@
"node": ">= 4"
}
},
+ "node_modules/immediate": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
+ "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==",
+ "license": "MIT"
+ },
"node_modules/import-fresh": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
@@ -3660,6 +3806,12 @@
"node": ">=0.8.19"
}
},
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "license": "ISC"
+ },
"node_modules/internal-slot": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz",
@@ -4126,7 +4278,6 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
- "dev": true,
"license": "MIT"
},
"node_modules/js-yaml": {
@@ -4205,6 +4356,18 @@
"node": ">=4.0"
}
},
+ "node_modules/jszip": {
+ "version": "3.10.1",
+ "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz",
+ "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==",
+ "license": "(MIT OR GPL-3.0-or-later)",
+ "dependencies": {
+ "lie": "~3.3.0",
+ "pako": "~1.0.2",
+ "readable-stream": "~2.3.6",
+ "setimmediate": "^1.0.5"
+ }
+ },
"node_modules/keyv": {
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
@@ -4249,6 +4412,15 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/lie": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
+ "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==",
+ "license": "MIT",
+ "dependencies": {
+ "immediate": "~3.0.5"
+ }
+ },
"node_modules/locate-path": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
@@ -4276,7 +4448,6 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
- "dev": true,
"license": "MIT",
"dependencies": {
"js-tokens": "^3.0.0 || ^4.0.0"
@@ -4299,7 +4470,6 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
@@ -4329,6 +4499,27 @@
"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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
@@ -4352,6 +4543,21 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/motion-dom": {
+ "version": "12.23.23",
+ "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.23.23.tgz",
+ "integrity": "sha512-n5yolOs0TQQBRUFImrRfs/+6X4p3Q4n1dUEqt/H58Vx7OW6RF+foWEgmTVDhIWJIMXOuNNL0apKH2S16en9eiA==",
+ "license": "MIT",
+ "dependencies": {
+ "motion-utils": "^12.23.6"
+ }
+ },
+ "node_modules/motion-utils": {
+ "version": "12.23.6",
+ "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.23.6.tgz",
+ "integrity": "sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ==",
+ "license": "MIT"
+ },
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
@@ -4463,7 +4669,6 @@
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@@ -4650,6 +4855,12 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/pako": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
+ "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
+ "license": "(MIT AND Zlib)"
+ },
"node_modules/parent-module": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
@@ -4757,11 +4968,16 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/process-nextick-args": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
+ "license": "MIT"
+ },
"node_modules/prop-types": {
"version": "15.8.1",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
- "dev": true,
"license": "MIT",
"dependencies": {
"loose-envify": "^1.4.0",
@@ -4769,6 +4985,12 @@
"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==",
+ "license": "MIT"
+ },
"node_modules/punycode": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
@@ -4809,6 +5031,19 @@
"node": ">=0.10.0"
}
},
+ "node_modules/react-async-script": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/react-async-script/-/react-async-script-1.2.0.tgz",
+ "integrity": "sha512-bCpkbm9JiAuMGhkqoAiC0lLkb40DJ0HOEJIku+9JDjxX3Rcs+ztEOG13wbrOskt3n2DTrjshhaQ/iay+SnGg5Q==",
+ "license": "MIT",
+ "dependencies": {
+ "hoist-non-react-statics": "^3.3.0",
+ "prop-types": "^15.5.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.4.1"
+ }
+ },
"node_modules/react-dom": {
"version": "19.2.0",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz",
@@ -4821,11 +5056,44 @@
"react": "^19.2.0"
}
},
+ "node_modules/react-google-recaptcha": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/react-google-recaptcha/-/react-google-recaptcha-3.1.0.tgz",
+ "integrity": "sha512-cYW2/DWas8nEKZGD7SCu9BSuVz8iOcOLHChHyi7upUuVhkpkhYG/6N3KDiTQ3XAiZ2UAZkfvYKMfAHOzBOcGEg==",
+ "license": "MIT",
+ "dependencies": {
+ "prop-types": "^15.5.0",
+ "react-async-script": "^1.2.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.4.1"
+ }
+ },
"node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
- "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/readable-stream": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+ "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+ "license": "MIT",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "node_modules/readable-stream/node_modules/isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
"license": "MIT"
},
"node_modules/reflect.getprototypeof": {
@@ -4968,6 +5236,12 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "license": "MIT"
+ },
"node_modules/safe-push-apply": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz",
@@ -5003,12 +5277,43 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/sax": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.3.tgz",
+ "integrity": "sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ==",
+ "license": "BlueOak-1.0.0"
+ },
"node_modules/scheduler": {
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz",
"integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==",
"license": "MIT"
},
+ "node_modules/selenium-webdriver": {
+ "version": "4.38.0",
+ "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-4.38.0.tgz",
+ "integrity": "sha512-5/UXXFSQmn7FGQkbcpAqvfhzflUdMWtT7QqpEgkFD6Q6rDucxB5EUfzgjmr6JbUj30QodcW3mDXehzoeS/Vy5w==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/SeleniumHQ"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/selenium"
+ }
+ ],
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@bazel/runfiles": "^6.3.1",
+ "jszip": "^3.10.1",
+ "tmp": "^0.2.5",
+ "ws": "^8.18.3"
+ },
+ "engines": {
+ "node": ">= 20.0.0"
+ }
+ },
"node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
@@ -5068,6 +5373,12 @@
"node": ">= 0.4"
}
},
+ "node_modules/setimmediate": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
+ "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==",
+ "license": "MIT"
+ },
"node_modules/sharp": {
"version": "0.34.5",
"resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz",
@@ -5225,6 +5536,40 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/sitemap": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-9.0.0.tgz",
+ "integrity": "sha512-J/SU27FJ+I52TcDLKZzPRRVQUMj0Pp1i/HLb2lrkU+hrMLM+qdeRjdacrNxnSW48Waa3UcEOGOdX1+0Lob7TgA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "^24.9.2",
+ "@types/sax": "^1.2.1",
+ "arg": "^5.0.0",
+ "sax": "^1.4.1"
+ },
+ "bin": {
+ "sitemap": "dist/esm/cli.js"
+ },
+ "engines": {
+ "node": ">=20.19.5",
+ "npm": ">=10.8.2"
+ }
+ },
+ "node_modules/sitemap/node_modules/@types/node": {
+ "version": "24.10.1",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.1.tgz",
+ "integrity": "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==",
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~7.16.0"
+ }
+ },
+ "node_modules/sitemap/node_modules/undici-types": {
+ "version": "7.16.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
+ "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
+ "license": "MIT"
+ },
"node_modules/source-map-js": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
@@ -5255,6 +5600,15 @@
"node": ">= 0.4"
}
},
+ "node_modules/string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
"node_modules/string.prototype.includes": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz",
@@ -5488,6 +5842,15 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
+ "node_modules/tmp": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz",
+ "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.14"
+ }
+ },
"node_modules/to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
@@ -5698,7 +6061,6 @@
"version": "6.21.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
- "dev": true,
"license": "MIT"
},
"node_modules/unrs-resolver": {
@@ -5777,6 +6139,12 @@
"punycode": "^2.1.0"
}
},
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+ "license": "MIT"
+ },
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
@@ -5892,6 +6260,49 @@
"node": ">=0.10.0"
}
},
+ "node_modules/ws": {
+ "version": "8.18.3",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz",
+ "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": ">=5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/xml2js": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz",
+ "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==",
+ "license": "MIT",
+ "dependencies": {
+ "sax": ">=0.6.0",
+ "xmlbuilder": "~11.0.0"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/xmlbuilder": {
+ "version": "11.0.1",
+ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
+ "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
"node_modules/yallist": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
diff --git a/package.json b/package.json
index f472a2d..07160a6 100644
--- a/package.json
+++ b/package.json
@@ -6,17 +6,25 @@
"dev": "next dev",
"build": "next build",
"start": "next start",
- "lint": "eslint"
+ "lint": "eslint",
+ "sitemap": "node scripts/generate-sitemap.cjs"
},
"dependencies": {
+ "axios": "^1.13.2",
+ "framer-motion": "^12.23.24",
"next": "16.0.3",
"react": "19.2.0",
- "react-dom": "19.2.0"
+ "react-dom": "19.2.0",
+ "react-google-recaptcha": "^3.1.0",
+ "selenium-webdriver": "^4.38.0",
+ "sitemap": "^9.0.0",
+ "xml2js": "^0.6.2"
},
"devDependencies": {
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",
+ "@types/react-google-recaptcha": "^2.1.9",
"eslint": "^9",
"eslint-config-next": "16.0.3",
"typescript": "^5"
diff --git a/public/images/about-testimonial-bg.jpg b/public/images/about-testimonial-bg.jpg
new file mode 100644
index 0000000..d4fedd7
Binary files /dev/null and b/public/images/about-testimonial-bg.jpg differ
diff --git a/public/images/footer-bg.png b/public/images/footer-bg.png
new file mode 100644
index 0000000..a78229d
Binary files /dev/null and b/public/images/footer-bg.png differ
diff --git a/public/images/section-bg.jpg b/public/images/section-bg.jpg
new file mode 100644
index 0000000..d4fedd7
Binary files /dev/null and b/public/images/section-bg.jpg differ
diff --git a/public/robots.txt b/public/robots.txt
new file mode 100644
index 0000000..3bf2014
--- /dev/null
+++ b/public/robots.txt
@@ -0,0 +1,6 @@
+# Allow all search engines to crawl all pages
+User-agent: *
+Disallow:
+
+# Sitemap
+Sitemap: http://localhost:3000/sitemap.xml
diff --git a/public/sitemap.xml b/public/sitemap.xml
new file mode 100644
index 0000000..5b4d207
--- /dev/null
+++ b/public/sitemap.xml
@@ -0,0 +1 @@
+http://localhost:3000/ daily 1.0 http://localhost:3000/about/ monthly 0.5 http://localhost:3000/menu/ weekly 0.6 http://localhost:3000/gallery/ weekly 0.6 http://localhost:3000/contact/ weekly 0.6 http://localhost:3000/blog/ weekly 0.6 http://localhost:3000/blog/the-art-of-turkish-tea/ weekly 0.6 http://localhost:3000/blog/secrets-of-charcoal-grilling/ weekly 0.6 http://localhost:3000/blog/a-taste-of-sweet-legacy/ weekly 0.6
\ No newline at end of file
diff --git a/scripts/generate-sitemap.cjs b/scripts/generate-sitemap.cjs
new file mode 100644
index 0000000..afd8673
--- /dev/null
+++ b/scripts/generate-sitemap.cjs
@@ -0,0 +1,66 @@
+const fs = require("fs");
+const path = require("path");
+const { SitemapStream, streamToPromise } = require("sitemap");
+const { pathToFileURL } = require("url");
+
+const hostname = "http://localhost:3000"; // localhost for development
+const addTrailingSlash = true; // ✅ Set this true if your Next.js uses trailingSlash: true
+
+// Utility to format URLs based on config
+const shouldAddSlash = (url) => {
+ if (url === "/") return false;
+ if (/\.[a-z0-9]{2,6}(\?.*)?$/i.test(url)) return false;
+ return true;
+};
+
+const formatUrl = (url) => {
+ if (!url.startsWith("/")) url = "/" + url;
+ if (addTrailingSlash && shouldAddSlash(url) && !url.endsWith("/")) {
+ return url + "/";
+ }
+ if (!addTrailingSlash && url.endsWith("/") && url !== "/") {
+ return url.slice(0, -1);
+ }
+ return url;
+};
+
+// ✅ Static pages
+const staticLinks = [
+ { url: '/', changefreq: 'daily', priority: 1.0 },
+ { url: '/about/', changefreq: 'monthly', priority: 0.5 },
+ { url: '/menu/', changefreq: 'weekly', priority: 0.6 },
+ { url: '/gallery/', changefreq: 'weekly', priority: 0.6 },
+ { url: '/contact/', changefreq: 'weekly', priority: 0.6 },
+ { url: '/blog/', changefreq: 'weekly', priority: 0.6 },
+];
+
+// ✅ Dynamic blog posts (only URLs, no extra metadata needed beyond static format)
+const blogPosts = [
+ { slug: '/blog/the-art-of-turkish-tea' },
+ { slug: '/blog/secrets-of-charcoal-grilling/' },
+ { slug: '/blog/a-taste-of-sweet-legacy/' },
+];
+
+const blogLinks = blogPosts.map(p => ({ url: p.slug, changefreq: 'weekly', priority: 0.6 }));
+
+const allLinks = [...staticLinks, ...blogLinks].map(l => ({ ...l, url: formatUrl(l.url) }));
+
+async function generateSitemap() {
+ try {
+ const sitemap = new SitemapStream({ hostname });
+ const writeStream = fs.createWriteStream(path.resolve(__dirname, "../public/sitemap.xml"));
+ sitemap.pipe(writeStream);
+ console.log('📦 Writing URLs to sitemap:');
+ allLinks.forEach(link => {
+ console.log(' -', hostname + link.url);
+ sitemap.write(link);
+ });
+ sitemap.end();
+ await streamToPromise(sitemap);
+ console.log('✅ sitemap.xml created successfully!');
+ } catch (error) {
+ console.error('❌ Error creating sitemap.xml:', error);
+ }
+}
+
+generateSitemap();
diff --git a/scripts/image_alt_issues.csv b/scripts/image_alt_issues.csv
new file mode 100644
index 0000000..eed7e97
--- /dev/null
+++ b/scripts/image_alt_issues.csv
@@ -0,0 +1,10 @@
+Page URL,Image Src,Alt Text,Issue Type
+"http://localhost:3000/","","Antalya Restaurant","Duplicate Alt (2 times)"
+"http://localhost:3000/about/","","Antalya Restaurant","Duplicate Alt (3 times)"
+"http://localhost:3000/menu/","","Antalya Restaurant","Duplicate Alt (3 times)"
+"http://localhost:3000/gallery/","","Antalya Restaurant","Duplicate Alt (3 times)"
+"http://localhost:3000/contact/","","Antalya Restaurant","Duplicate Alt (3 times)"
+"http://localhost:3000/blog/","","Antalya Restaurant","Duplicate Alt (3 times)"
+"http://localhost:3000/blog/the-art-of-turkish-tea/","","Antalya Restaurant","Duplicate Alt (3 times)"
+"http://localhost:3000/blog/secrets-of-charcoal-grilling/","","Antalya Restaurant","Duplicate Alt (3 times)"
+"http://localhost:3000/blog/a-taste-of-sweet-legacy/","","Antalya Restaurant","Duplicate Alt (3 times)"
diff --git a/scripts/seo-test-selenium.cjs b/scripts/seo-test-selenium.cjs
new file mode 100644
index 0000000..dd1c342
--- /dev/null
+++ b/scripts/seo-test-selenium.cjs
@@ -0,0 +1,244 @@
+const { Builder, By } = require("selenium-webdriver");
+const chrome = require("selenium-webdriver/chrome");
+const axios = require("axios");
+const xml2js = require("xml2js");
+const fs = require("fs");
+const path = require("path");
+
+// CSV file for Image Alt issues
+const csvPath = path.join(__dirname, "image_alt_issues.csv");
+fs.writeFileSync(csvPath, "Page URL,Image Src,Alt Text,Issue Type\n", "utf8");
+
+// ==========================
+// 1️⃣ Fetch URLs from sitemap.xml
+// ==========================
+async function getUrlsFromSitemap(sitemapUrl) {
+ try {
+ const res = await axios.get(sitemapUrl);
+ const parsed = await xml2js.parseStringPromise(res.data);
+ return parsed.urlset.url.map((u) => u.loc[0]);
+ } catch (err) {
+ console.error("❌ Failed to load sitemap:", err.message);
+ return [];
+ }
+}
+
+// ==========================
+// 2️⃣ Check HTTP Status
+// ==========================
+async function checkLinkStatus(url) {
+ try {
+ const res = await axios.get(url, {
+ timeout: 10000,
+ validateStatus: () => true,
+ });
+ if (res.status === 200 && res.data.toLowerCase().includes("page not found")) {
+ return "Soft 404";
+ }
+ return res.status;
+ } catch (err) {
+ return err.response ? err.response.status : "❌ No Response";
+ }
+}
+
+// ==========================
+// 3️⃣ Main SEO + Accessibility + Image Alt Audit
+// ==========================
+async function checkSEO(url, siteDomain) {
+ const options = new chrome.Options();
+ options.addArguments("--headless", "--no-sandbox", "--disable-gpu");
+ const driver = await new Builder()
+ .forBrowser("chrome")
+ .setChromeOptions(options)
+ .build();
+
+ try {
+ const pageStatus = await checkLinkStatus(url);
+ if (pageStatus === 404 || pageStatus === "Soft 404") {
+ console.log(`\n🚫 ${url} → ❌ Page not found (${pageStatus})`);
+ return;
+ }
+
+ await driver.get(url);
+ const pageSource = await driver.getPageSource();
+
+ // Basic SEO Elements
+ const title = await driver.getTitle();
+ const descElem = await driver.findElements(By.css('meta[name="description"]'));
+ const canonicalElem = await driver.findElements(By.css('link[rel="canonical"]'));
+ const robotsElem = await driver.findElements(By.css('meta[name="robots"]'));
+ const viewportElem = await driver.findElements(By.css('meta[name="viewport"]'));
+ const charset = await driver.findElements(By.css('meta[charset]'));
+ const htmlTag = await driver.findElement(By.css("html"));
+ const langAttr = await htmlTag.getAttribute("lang").catch(() => "");
+ const h1Tags = await driver.findElements(By.css("h1"));
+ const h2Tags = await driver.findElements(By.css("h2"));
+
+ // Meta Description
+ let descContent = descElem.length > 0 ? await descElem[0].getAttribute("content") : "";
+ const descLength = descContent.length;
+ const descStatus =
+ descLength === 0
+ ? "❌ Missing"
+ : descLength < 50
+ ? `⚠️ Too short (${descLength})`
+ : descLength > 160
+ ? `⚠️ Too long (${descLength})`
+ : "✅ Perfect";
+
+ // Title length check
+ const titleLength = title.length;
+ const titleStatus =
+ titleLength === 0
+ ? "❌ Missing"
+ : titleLength < 30
+ ? `⚠️ Too short (${titleLength})`
+ : titleLength > 65
+ ? `⚠️ Too long (${titleLength})`
+ : "✅ Perfect";
+
+ // Canonical
+ const canonicalURL = canonicalElem.length > 0 ? await canonicalElem[0].getAttribute("href") : "❌ Missing";
+
+ // 🖼️ Image Accessibility Audit
+ const imgs = await driver.findElements(By.css("img"));
+ let missingAlt = 0;
+ let emptyAlt = 0;
+ let duplicateAlt = [];
+ const altTextMap = new Map();
+
+ for (const img of imgs) {
+ const src = await img.getAttribute("src");
+ const alt = (await img.getAttribute("alt"))?.trim() ?? null;
+
+ if (alt === null) {
+ missingAlt++;
+ fs.appendFileSync(csvPath, `"${url}","${src}","","Missing Alt"\n`, "utf8");
+ continue;
+ }
+
+ if (alt === "") {
+ emptyAlt++;
+ fs.appendFileSync(csvPath, `"${url}","${src}","(empty)","Empty Alt"\n`, "utf8");
+ }
+
+ if (altTextMap.has(alt)) {
+ altTextMap.set(alt, altTextMap.get(alt) + 1);
+ } else {
+ altTextMap.set(alt, 1);
+ }
+ }
+
+ for (const [altText, count] of altTextMap.entries()) {
+ if (altText && count > 1) {
+ duplicateAlt.push({ altText, count });
+ fs.appendFileSync(
+ csvPath,
+ `"${url}","","${altText}","Duplicate Alt (${count} times)"\n`,
+ "utf8"
+ );
+ }
+ }
+
+ // Detect tracking & schema tags
+ const hasGTM = pageSource.includes("googletagmanager.com/gtm.js");
+ const hasClarity = pageSource.includes("clarity.ms/tag");
+ const hasFBPixel = pageSource.includes("fbevents.js") || pageSource.includes("fbq(");
+ const hasAnalytics = pageSource.includes("www.googletagmanager.com/gtag/js");
+
+ const ogTags = await driver.findElements(By.css("meta[property^='og:']"));
+ const twitterTags = await driver.findElements(By.css("meta[name^='twitter:']"));
+ const schemaScripts = await driver.findElements(By.css('script[type="application/ld+json"]'));
+
+ // Links check
+ const anchorTags = await driver.findElements(By.css("a[href]"));
+ const brokenLinks = [];
+ for (const a of anchorTags) {
+ const href = await a.getAttribute("href");
+ if (!href || href.startsWith("#") || href.startsWith("mailto:")) continue;
+
+ const fullUrl = href.startsWith("http")
+ ? href
+ : `${siteDomain}${href.startsWith("/") ? href : `/${href}`}`;
+
+ if (fullUrl.includes(siteDomain)) {
+ const status = await checkLinkStatus(fullUrl);
+ if (status === 404 || status === "Soft 404" || status === "❌ No Response") {
+ brokenLinks.push({ link: fullUrl, status });
+ }
+ }
+ }
+
+ // Lazy loading check
+ const mediaElems = await driver.findElements(By.css("img, video, iframe"));
+ const lazyLoadCount = await Promise.all(
+ mediaElems.map(async (el) => {
+ const loading = await el.getAttribute("loading");
+ return loading === "lazy";
+ })
+ );
+ const lazyLoaded = lazyLoadCount.filter((v) => v).length;
+
+ // Console Summary
+ console.log(`\n🔍 Checking: ${url}`);
+ console.log("-------------------------------------------");
+ console.log("Title:", titleStatus);
+ console.log("Meta Description:", descStatus);
+ console.log("Canonical URL:", canonicalURL);
+ console.log("Meta Robots:", robotsElem.length > 0 ? "✅ Found" : "⚠️ Missing");
+ console.log("Viewport:", viewportElem.length > 0 ? "✅ Found" : "⚠️ Missing");
+ console.log("Charset:", charset.length > 0 ? "✅ Found" : "❌ Missing");
+ console.log("HTML lang:", langAttr ? `✅ ${langAttr}` : "⚠️ Missing");
+ console.log("H1 Tags:", h1Tags.length > 0 ? `✅ ${h1Tags.length}` : "❌ Missing");
+ console.log("H2 Tags:", h2Tags.length > 0 ? `ℹ️ ${h2Tags.length}` : "⚠️ None");
+ console.log("Images:", imgs.length);
+ console.log("Missing Alt:", missingAlt > 0 ? `❌ ${missingAlt}` : "✅ None");
+ console.log("Empty Alt:", emptyAlt > 0 ? `⚠️ ${emptyAlt}` : "✅ None");
+ console.log("Duplicate Alt:", duplicateAlt.length > 0 ? `⚠️ ${duplicateAlt.length}` : "✅ None");
+ console.log("Lazy Loaded Images:", lazyLoaded > 0 ? `✅ ${lazyLoaded}` : "⚠️ None");
+ console.log("Open Graph Tags:", ogTags.length > 0 ? "✅ Found" : "⚠️ Missing");
+ console.log("Twitter Tags:", twitterTags.length > 0 ? "✅ Found" : "⚠️ Missing");
+ console.log("Schema Markup:", schemaScripts.length > 0 ? "✅ Found" : "⚠️ Missing");
+ console.log("Google Analytics:", hasAnalytics ? "✅ Found" : "⚠️ Missing");
+ console.log("GTM:", hasGTM ? "✅ Found" : "⚠️ Missing");
+ console.log("Clarity:", hasClarity ? "✅ Found" : "⚠️ Missing");
+ console.log("Facebook Pixel:", hasFBPixel ? "✅ Found" : "⚠️ Missing");
+
+ if (brokenLinks.length > 0) {
+ console.log("\n❌ Broken Links:");
+ brokenLinks.forEach((b) => console.log(` → ${b.link} [${b.status}]`));
+ } else {
+ console.log("✅ No broken links found.");
+ }
+ } catch (err) {
+ console.error(`❌ Error on ${url}:`, err.message);
+ } finally {
+ await driver.quit();
+ }
+}
+
+// ==========================
+// 4️⃣ Run Full Site Audit
+// ==========================
+(async () => {
+ const sitemapUrl = "http://localhost:3000/sitemap.xml";
+ const siteDomain = "http://localhost:3000";
+
+ console.log("📄 Fetching URLs from sitemap...");
+ const urls = await getUrlsFromSitemap(sitemapUrl);
+
+ if (urls.length === 0) {
+ console.error("❌ No URLs found in sitemap.");
+ return;
+ }
+
+ console.log(`✅ Found ${urls.length} URLs in sitemap.`);
+ console.log("🚀 Starting Full SEO + Accessibility + Broken Link Audit...");
+
+ for (const url of urls) {
+ await checkSEO(url, siteDomain);
+ }
+
+ console.log("\n✅ Full SEO Audit Completed!");
+ console.log(`📁 CSV Report: ${csvPath}`);
+})();
diff --git a/src/app/about/about.module.css b/src/app/about/about.module.css
new file mode 100644
index 0000000..dfa8fa8
--- /dev/null
+++ b/src/app/about/about.module.css
@@ -0,0 +1,575 @@
+.main {
+ background-color: var(--color-dark);
+ color: var(--color-text-light);
+ min-height: 100vh;
+}
+
+.hero {
+ padding: 10rem 2rem;
+ background: linear-gradient(rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.6)), url('/images/hero-1.png');
+ background-size: cover;
+ background-position: center;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ text-align: center;
+}
+
+.heroContent {
+ max-width: 800px;
+}
+
+.heroTitle {
+ font-family: var(--font-playfair);
+ font-size: 4rem;
+ color: var(--color-gold);
+ margin-bottom: 1rem;
+ text-transform: uppercase;
+ letter-spacing: 2px;
+}
+
+.breadcrumb {
+ font-size: 1.1rem;
+ color: #C5A059;
+ font-family: var(--font-lato);
+}
+
+.breadcrumb a {
+ color: #fff;
+ transition: color 0.3s;
+}
+
+.breadcrumb a:hover {
+ color: var(--color-gold);
+}
+
+.section {
+ padding: 80px 20px;
+ background-color: #f5e6d3;
+}
+
+.featuresSection {
+ background-color: #3a0c08;
+ background-image: url('/images/section-bg.jpg');
+ background-size: cover;
+ background-position: center;
+}
+
+.testimonialsSection {
+ background-color: #3a0c08;
+ background-image: url('/images/about-testimonial-bg.jpg');
+ background-size: cover;
+ background-position: center;
+ background-repeat: repeat;
+}
+
+.container {
+ max-width: 1200px;
+ margin: 0 auto;
+ display: flex;
+ align-items: center;
+ gap: 4rem;
+ flex-wrap: wrap;
+}
+
+.textBlock {
+ flex: 1;
+ min-width: 300px;
+}
+
+.imageBlock {
+ flex: 1;
+ min-width: 300px;
+ display: flex;
+ justify-content: center;
+}
+
+.sectionTitle {
+ font-family: var(--font-playfair);
+ font-size: 3rem;
+ color: #5d4037;
+ margin-bottom: 1.5rem;
+ text-transform: uppercase;
+ letter-spacing: 2px;
+}
+
+.sectionTitleCenter {
+ font-family: var(--font-playfair);
+ font-size: 3.5rem;
+ color: #C5A059;
+ margin-bottom: 3rem;
+ text-align: center;
+ text-transform: uppercase;
+ letter-spacing: 2px;
+}
+
+.text {
+ font-size: 1.1rem;
+ line-height: 1.8;
+ color: #5d4037;
+ margin-bottom: 1.5rem;
+ opacity: 0.9;
+ font-family: var(--font-lato);
+}
+
+.image {
+ border-radius: 8px;
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
+ max-width: 100%;
+ height: auto;
+ border: 4px solid #C5A059;
+}
+
+.menuButton {
+ display: inline-block;
+ padding: 15px 40px;
+ border: 2px solid #C5A059;
+ color: #C5A059;
+ font-family: var(--font-lato);
+ font-size: 1.1rem;
+ text-transform: uppercase;
+ text-decoration: none;
+ transition: all 0.3s ease;
+ background: transparent;
+ letter-spacing: 1px;
+ margin-top: 1rem;
+}
+
+.menuButton:hover {
+ background-color: #C5A059;
+ color: #000;
+}
+
+/* Features Section */
+.featuresGrid {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ gap: 3rem;
+ max-width: 1200px;
+ margin: 0 auto;
+}
+
+.featureCard {
+ background-color: #F5E6D3;
+ padding: 2.5rem 2rem;
+ text-align: center;
+ border: 4px solid #C5A059;
+ transition: transform 0.3s ease;
+}
+
+.featureCard:hover {
+ transform: translateY(-10px);
+}
+
+.featureImageWrapper {
+ position: relative;
+ width: 100%;
+ height: 200px;
+ margin-bottom: 1.5rem;
+ border-radius: 8px;
+ overflow: hidden;
+ border: 2px solid #C5A059;
+}
+
+.featureImage {
+ object-fit: cover;
+}
+
+.featureTitle {
+ font-family: var(--font-playfair);
+ font-size: 1.8rem;
+ color: #3e2723;
+ margin-bottom: 1rem;
+ font-weight: 600;
+}
+
+.featureDesc {
+ font-family: var(--font-lato);
+ font-size: 1rem;
+ color: #5d4037;
+ line-height: 1.6;
+}
+
+/* Testimonials Slider */
+.testimonialSlider {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 2rem;
+ max-width: 900px;
+ margin: 0 auto;
+ position: relative;
+}
+
+.sliderBtn {
+ background: transparent;
+ border: 2px solid #C5A059;
+ color: #C5A059;
+ font-size: 2.5rem;
+ width: 50px;
+ height: 50px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ cursor: pointer;
+ transition: all 0.3s;
+ flex-shrink: 0;
+}
+
+.sliderBtn:hover {
+ background-color: #C5A059;
+ color: #000;
+}
+
+.testimonialCard {
+ background-color: #F5E6D3;
+ padding: 3rem 2.5rem;
+ border: 4px solid #C5A059;
+ display: flex;
+ flex-direction: column;
+ gap: 2rem;
+ flex: 1;
+ min-height: 300px;
+}
+
+.testimonialText {
+ font-family: var(--font-lato);
+ font-size: 1.3rem;
+ color: #5d4037;
+ line-height: 1.8;
+ font-style: italic;
+ text-align: center;
+}
+
+.testimonialAuthor {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 1.5rem;
+}
+
+.authorImageWrapper {
+ position: relative;
+ width: 70px;
+ height: 70px;
+ border-radius: 50%;
+ overflow: hidden;
+ border: 3px solid #C5A059;
+ flex-shrink: 0;
+}
+
+.authorImage {
+ object-fit: cover;
+}
+
+.authorInfo {
+ display: flex;
+ flex-direction: column;
+ text-align: left;
+}
+
+.authorName {
+ font-family: var(--font-playfair);
+ font-size: 1.2rem;
+ color: #3e2723;
+ font-weight: 600;
+}
+
+.authorRole {
+ font-family: var(--font-lato);
+ font-size: 0.95rem;
+ color: #836839;
+}
+
+.sliderDots {
+ display: flex;
+ justify-content: center;
+ gap: 1rem;
+ margin-top: 2rem;
+}
+
+.dot {
+ width: 12px;
+ height: 12px;
+ border-radius: 50%;
+ background: transparent;
+ border: 2px solid #C5A059;
+ cursor: pointer;
+ transition: all 0.3s;
+ padding: 0;
+}
+
+.dot:hover,
+.activeDot {
+ background-color: #C5A059;
+}
+
+/* Call to Action Section */
+.ctaSection {
+ padding: 5rem 2rem;
+ background-size: cover;
+ background-position: center;
+ position: relative;
+ text-align: center;
+}
+
+.ctaOverlay {
+ position: relative;
+ z-index: 2;
+ background: rgba(58, 12, 8, 0.9);
+ padding: 4rem 2rem;
+ max-width: 800px;
+ margin: 0 auto;
+ border: 4px solid #C5A059;
+}
+
+.ctaTitle {
+ font-family: var(--font-playfair);
+ font-size: 3rem;
+ color: #C5A059;
+ margin-bottom: 1rem;
+ text-transform: uppercase;
+ letter-spacing: 2px;
+}
+
+.ctaSubtitle {
+ font-family: var(--font-lato);
+ font-size: 1.3rem;
+ color: #F5E6D3;
+ margin-bottom: 2rem;
+}
+
+.ctaButton {
+ display: inline-block;
+ padding: 15px 40px;
+ border: 2px solid #C5A059;
+ color: #C5A059;
+ font-family: var(--font-lato);
+ font-size: 1.1rem;
+ text-transform: uppercase;
+ text-decoration: none;
+ transition: all 0.3s ease;
+ background: transparent;
+ letter-spacing: 1px;
+}
+
+.ctaButton:hover {
+ background-color: #C5A059;
+ color: #000;
+}
+
+@media (max-width: 1024px) {
+ .featuresGrid {
+ grid-template-columns: 1fr;
+ }
+
+ .testimonialSlider {
+ flex-direction: column;
+ }
+
+ .sliderBtn {
+ order: 2;
+ }
+
+ .testimonialCard {
+ order: 1;
+ }
+
+ .faqContainer {
+ grid-template-columns: 1fr;
+ gap: 3rem;
+ }
+
+ .faqImageBlock {
+ min-height: 400px;
+ }
+}
+
+@media (max-width: 768px) {
+ .heroTitle {
+ font-size: 3rem;
+ }
+
+ .container {
+ flex-direction: column;
+ gap: 2rem;
+ }
+
+ .section {
+ padding: 60px 20px;
+ }
+
+ .sectionTitleCenter {
+ font-size: 2rem;
+ }
+
+ .ctaTitle {
+ font-size: 2rem;
+ }
+
+ .sliderBtn {
+ width: 40px;
+ height: 40px;
+ font-size: 2rem;
+ }
+
+ .faqSection {
+ padding: 60px 20px;
+ }
+
+ .faqTitle {
+ font-size: 2rem;
+ }
+
+ .faqSubtitle {
+ font-size: 1rem;
+ }
+
+ .faqQuestion {
+ padding: 1.2rem 1.5rem;
+ font-size: 1rem;
+ }
+
+ .faqAnswer {
+ padding: 1.2rem 1.5rem;
+ }
+
+ .faqImageBlock {
+ min-height: 300px;
+ }
+}
+
+/* FAQ Section Styles */
+.faqSection {
+ padding: 80px 20px;
+ background-color: #F5E6D3;
+}
+
+.faqContainer {
+ max-width: 1400px;
+ margin: 0 auto;
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 4rem;
+ align-items: start;
+}
+
+.faqImageBlock {
+ position: relative;
+ width: 100%;
+ height: 100%;
+ min-height: 600px;
+}
+
+.faqImage {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ border-radius: 12px;
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
+}
+
+.faqContentBlock {
+ display: flex;
+ flex-direction: column;
+ gap: 2rem;
+}
+
+.faqTitle {
+ font-family: var(--font-playfair);
+ font-size: 2.5rem;
+ color: #5d4037;
+ margin-bottom: 0.5rem;
+}
+
+.faqSubtitle {
+ font-family: var(--font-lato);
+ font-size: 1.1rem;
+ color: #836839;
+ line-height: 1.6;
+ margin-bottom: 1rem;
+}
+
+.faqAccordion {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+}
+
+.faqItem {
+ background: #fff;
+ border: 2px solid #C5A059;
+ border-radius: 8px;
+ overflow: hidden;
+ transition: all 0.3s ease;
+}
+
+.faqItem:hover {
+ box-shadow: 0 4px 12px rgba(197, 160, 89, 0.2);
+}
+
+.faqQuestion {
+ width: 100%;
+ padding: 1.5rem 2rem;
+ background: transparent;
+ border: none;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ cursor: pointer;
+ font-family: var(--font-lato);
+ font-size: 1.1rem;
+ font-weight: 600;
+ color: #5d4037;
+ text-align: left;
+ transition: all 0.3s ease;
+}
+
+.faqQuestion:hover {
+ background-color: #faf6f0;
+}
+
+.faqQuestionActive {
+ background-color: #C5A059;
+ color: #fff;
+}
+
+.faqIcon {
+ font-size: 1.5rem;
+ font-weight: bold;
+ color: #C5A059;
+ transition: transform 0.3s ease;
+ flex-shrink: 0;
+ margin-left: 1rem;
+}
+
+.faqQuestionActive .faqIcon {
+ color: #fff;
+ transform: rotate(180deg);
+}
+
+.faqAnswer {
+ padding: 1.5rem 2rem;
+ border-top: 1px solid #e0d5c7;
+ animation: slideDown 0.3s ease;
+}
+
+.faqAnswer p {
+ font-family: var(--font-lato);
+ font-size: 1rem;
+ color: #5d4037;
+ line-height: 1.8;
+ margin: 0;
+}
+
+@keyframes slideDown {
+ from {
+ opacity: 0;
+ transform: translateY(-10px);
+ }
+
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
\ No newline at end of file
diff --git a/src/app/about/about.module.css.backup b/src/app/about/about.module.css.backup
new file mode 100644
index 0000000..b0e050e
--- /dev/null
+++ b/src/app/about/about.module.css.backup
@@ -0,0 +1,770 @@
+.main {
+ background-color: var(--color-dark);
+ color: var(--color-text-light);
+ min-height: 100vh;
+}
+
+.hero {
+ padding: 10rem 2rem;
+ background: linear-gradient(rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.6)), url('/images/hero-1.png');
+ background-size: cover;
+ background-position: center;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ text-align: center;
+}
+
+.heroContent {
+ max-width: 800px;
+}
+
+.heroTitle {
+ font-family: var(--font-playfair);
+ font-size: 4rem;
+ color: var(--color-gold);
+ margin-bottom: 1rem;
+ text-transform: uppercase;
+ letter-spacing: 2px;
+}
+
+.breadcrumb {
+ font-size: 1.1rem;
+ color: #C5A059;
+ font-family: var(--font-lato);
+}
+
+.breadcrumb a {
+ color: #fff;
+ transition: color 0.3s;
+}
+
+.breadcrumb a:hover {
+ color: var(--color-gold);
+}
+
+.section {
+ padding: 80px 20px;
+ background-color: #0a0a0a;
+}
+
+.featuresSection {
+ background-color: #3a0c08;
+ background-image: url('/images/section-bg.jpg');
+ background-size: cover;
+ background-position: center;
+}
+
+.testimonialsSection {
+ background-color: #0a0a0a;
+}
+
+.container {
+ max-width: 1200px;
+ margin: 0 auto;
+ display: flex;
+ align-items: center;
+ gap: 4rem;
+ flex-wrap: wrap;
+}
+
+.textBlock {
+ flex: 1;
+ min-width: 300px;
+}
+
+.imageBlock {
+ flex: 1;
+ min-width: 300px;
+ display: flex;
+ justify-content: center;
+}
+
+.sectionTitle {
+ font-family: var(--font-playfair);
+ font-size: 3rem;
+ color: #C5A059;
+ margin-bottom: 1.5rem;
+ text-transform: uppercase;
+ letter-spacing: 2px;
+}
+
+.sectionTitleCenter {
+ font-family: var(--font-playfair);
+ font-size: 3.5rem;
+ color: #C5A059;
+ margin-bottom: 3rem;
+ text-align: center;
+ text-transform: uppercase;
+ letter-spacing: 2px;
+}
+
+.text {
+ font-size: 1.1rem;
+ line-height: 1.8;
+ color: #C5A059;
+ margin-bottom: 1.5rem;
+ opacity: 0.9;
+ font-family: var(--font-lato);
+}
+
+.image {
+ border-radius: 8px;
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
+ max-width: 100%;
+ height: auto;
+ border: 4px solid #C5A059;
+}
+
+.menuButton {
+ display: inline-block;
+ padding: 15px 40px;
+ border: 2px solid #C5A059;
+ color: #C5A059;
+ font-family: var(--font-lato);
+ font-size: 1.1rem;
+ text-transform: uppercase;
+ text-decoration: none;
+ transition: all 0.3s ease;
+ background: transparent;
+ letter-spacing: 1px;
+ margin-top: 1rem;
+}
+
+.menuButton:hover {
+ background-color: #C5A059;
+ color: #000;
+}
+
+/* Features Section */
+.featuresGrid {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ gap: 3rem;
+ max-width: 1200px;
+ margin: 0 auto;
+}
+
+.featureCard {
+ background-color: #F5E6D3;
+ padding: 2.5rem 2rem;
+ text-align: center;
+ border: 4px solid #C5A059;
+ transition: transform 0.3s ease;
+}
+
+.featureCard:hover {
+ transform: translateY(-10px);
+}
+
+.featureImageWrapper {
+ position: relative;
+ width: 100%;
+ height: 200px;
+ margin-bottom: 1.5rem;
+ border-radius: 8px;
+ overflow: hidden;
+ border: 2px solid #C5A059;
+}
+
+.featureImage {
+ object-fit: cover;
+}
+
+.featureTitle {
+ font-family: var(--font-playfair);
+ font-size: 1.8rem;
+ color: #3e2723;
+ margin-bottom: 1rem;
+ font-weight: 600;
+}
+
+.featureDesc {
+ font-family: var(--font-lato);
+ font-size: 1rem;
+ color: #5d4037;
+ line-height: 1.6;
+}
+
+/* Testimonials Slider */
+.testimonialSlider {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 2rem;
+ max-width: 900px;
+ margin: 0 auto;
+ position: relative;
+}
+
+.sliderBtn {
+ background: transparent;
+ border: 2px solid #C5A059;
+ color: #C5A059;
+ font-size: 2.5rem;
+ width: 50px;
+ height: 50px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ cursor: pointer;
+ transition: all 0.3s;
+ flex-shrink: 0;
+}
+
+.sliderBtn:hover {
+ background-color: #C5A059;
+ color: #000;
+}
+
+.testimonialCard {
+ background-color: #F5E6D3;
+ padding: 3rem 2.5rem;
+ border: 4px solid #C5A059;
+ display: flex;
+ flex-direction: column;
+ gap: 2rem;
+ flex: 1;
+ min-height: 300px;
+}
+
+.testimonialText {
+ font-family: var(--font-lato);
+ font-size: 1.3rem;
+ color: #5d4037;
+ line-height: 1.8;
+ font-style: italic;
+ text-align: center;
+}
+
+.testimonialAuthor {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 1.5rem;
+}
+
+.authorImageWrapper {
+ position: relative;
+ width: 70px;
+ height: 70px;
+ border-radius: 50%;
+ overflow: hidden;
+ border: 3px solid #C5A059;
+ flex-shrink: 0;
+}
+
+.authorImage {
+ object-fit: cover;
+}
+
+.authorInfo {
+ display: flex;
+ flex-direction: column;
+ text-align: left;
+}
+
+.authorName {
+ font-family: var(--font-playfair);
+ font-size: 1.2rem;
+ color: #3e2723;
+ font-weight: 600;
+}
+
+.authorRole {
+ font-family: var(--font-lato);
+ font-size: 0.95rem;
+ color: #836839;
+}
+
+.sliderDots {
+ display: flex;
+ justify-content: center;
+ gap: 1rem;
+ margin-top: 2rem;
+}
+
+.dot {
+ width: 12px;
+ height: 12px;
+ border-radius: 50%;
+ background: transparent;
+ border: 2px solid #C5A059;
+ cursor: pointer;
+ transition: all 0.3s;
+ padding: 0;
+}
+
+.dot:hover,
+.activeDot {
+ background-color: #C5A059;
+}
+
+/* Call to Action Section */
+.ctaSection {
+ padding: 5rem 2rem;
+ background-size: cover;
+ background-position: center;
+ position: relative;
+ text-align: center;
+}
+
+.ctaOverlay {
+ position: relative;
+ z-index: 2;
+ background: rgba(58, 12, 8, 0.9);
+ padding: 4rem 2rem;
+ max-width: 800px;
+ margin: 0 auto;
+ border: 4px solid #C5A059;
+}
+
+.ctaTitle {
+ font-family: var(--font-playfair);
+ font-size: 3rem;
+ color: #C5A059;
+ margin-bottom: 1rem;
+ text-transform: uppercase;
+ letter-spacing: 2px;
+}
+
+.ctaSubtitle {
+ font-family: var(--font-lato);
+ font-size: 1.3rem;
+ color: #F5E6D3;
+ margin-bottom: 2rem;
+}
+
+.ctaButton {
+ display: inline-block;
+ padding: 15px 40px;
+ border: 2px solid #C5A059;
+ color: #C5A059;
+ font-family: var(--font-lato);
+ font-size: 1.1rem;
+ text-transform: uppercase;
+ text-decoration: none;
+ transition: all 0.3s ease;
+ background: transparent;
+ letter-spacing: 1px;
+}
+
+.ctaButton:hover {
+ background-color: #C5A059;
+ color: #000;
+}
+
+@media (max-width: 1024px) {
+ .featuresGrid {
+ grid-template-columns: 1fr;
+ }
+
+ .testimonialSlider {
+ flex-direction: column;
+ }
+
+ .sliderBtn {
+ order: 2;
+ }
+
+ font-family: var(--font-playfair);
+ font-size: 1.8rem;
+ color: #3e2723;
+ margin-bottom: 1rem;
+ font-weight: 600;
+}
+
+.featureDesc {
+ font-family: var(--font-lato);
+ font-size: 1rem;
+ color: #5d4037;
+ line-height: 1.6;
+}
+
+/* Testimonials Slider */
+.testimonialSlider {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 2rem;
+ max-width: 900px;
+ margin: 0 auto;
+ position: relative;
+}
+
+.sliderBtn {
+ background: transparent;
+ border: 2px solid #C5A059;
+ color: #C5A059;
+ font-size: 2.5rem;
+ width: 50px;
+ height: 50px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ cursor: pointer;
+ transition: all 0.3s;
+ flex-shrink: 0;
+}
+
+.sliderBtn:hover {
+ background-color: #C5A059;
+ color: #000;
+}
+
+.testimonialCard {
+ background-color: #F5E6D3;
+ padding: 3rem 2.5rem;
+ border: 4px solid #C5A059;
+ display: flex;
+ flex-direction: column;
+ gap: 2rem;
+ flex: 1;
+ min-height: 300px;
+}
+
+.testimonialText {
+ font-family: var(--font-lato);
+ font-size: 1.3rem;
+ color: #5d4037;
+ line-height: 1.8;
+ font-style: italic;
+ text-align: center;
+}
+
+.testimonialAuthor {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 1.5rem;
+}
+
+.authorImageWrapper {
+ position: relative;
+ width: 70px;
+ height: 70px;
+ border-radius: 50%;
+ overflow: hidden;
+ border: 3px solid #C5A059;
+ flex-shrink: 0;
+}
+
+.authorImage {
+ object-fit: cover;
+}
+
+.authorInfo {
+ display: flex;
+ flex-direction: column;
+ text-align: left;
+}
+
+.authorName {
+ font-family: var(--font-playfair);
+ font-size: 1.2rem;
+ color: #3e2723;
+ font-weight: 600;
+}
+
+.authorRole {
+ font-family: var(--font-lato);
+ font-size: 0.95rem;
+ color: #836839;
+}
+
+.sliderDots {
+ display: flex;
+ justify-content: center;
+ gap: 1rem;
+ margin-top: 2rem;
+}
+
+.dot {
+ width: 12px;
+ height: 12px;
+ border-radius: 50%;
+ background: transparent;
+ border: 2px solid #C5A059;
+ cursor: pointer;
+ transition: all 0.3s;
+ padding: 0;
+}
+
+.dot:hover,
+.activeDot {
+ background-color: #C5A059;
+}
+
+/* Call to Action Section */
+.ctaSection {
+ padding: 5rem 2rem;
+ background-size: cover;
+ background-position: center;
+ position: relative;
+ text-align: center;
+}
+
+.ctaOverlay {
+ position: relative;
+ z-index: 2;
+ background: rgba(58, 12, 8, 0.9);
+ padding: 4rem 2rem;
+ max-width: 800px;
+ margin: 0 auto;
+ border: 4px solid #C5A059;
+}
+
+.ctaTitle {
+ font-family: var(--font-playfair);
+ font-size: 3rem;
+ color: #C5A059;
+ margin-bottom: 1rem;
+ text-transform: uppercase;
+ letter-spacing: 2px;
+}
+
+.ctaSubtitle {
+ font-family: var(--font-lato);
+ font-size: 1.3rem;
+ color: #F5E6D3;
+ margin-bottom: 2rem;
+}
+
+.ctaButton {
+ display: inline-block;
+ padding: 15px 40px;
+ border: 2px solid #C5A059;
+ color: #C5A059;
+ font-family: var(--font-lato);
+ font-size: 1.1rem;
+ text-transform: uppercase;
+ text-decoration: none;
+ transition: all 0.3s ease;
+ background: transparent;
+ letter-spacing: 1px;
+}
+
+.ctaButton:hover {
+ background-color: #C5A059;
+ color: #000;
+}
+
+@media (max-width: 1024px) {
+ .featuresGrid {
+ grid-template-columns: 1fr;
+ }
+
+ .testimonialSlider {
+ flex-direction: column;
+ }
+
+ .sliderBtn {
+ order: 2;
+ }
+
+ .testimonialCard {
+ order: 1;
+ }
+}
+
+@media (max-width: 768px) {
+ .heroTitle {
+ font-size: 3rem;
+ }
+
+ .container {
+ flex-direction: column;
+ gap: 2rem;
+ }
+
+ .section {
+ padding: 60px 20px;
+ }
+
+ .sectionTitleCenter {
+ font-size: 2rem;
+ }
+
+ .ctaTitle {
+ font-size: 2rem;
+ }
+
+ .sliderBtn {
+ width: 40px;
+ height: 40px;
+ font-size: 2rem;
+ }
+}
+
+/* FAQ Section Styles */
+.faqSection {
+ padding: 80px 20px;
+ background-color: #F5E6D3;
+}
+
+.faqContainer {
+ max-width: 1400px;
+ margin: 0 auto;
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 4rem;
+ align-items: start;
+}
+
+.faqImageBlock {
+ position: relative;
+ width: 100%;
+ height: 100%;
+ min-height: 600px;
+}
+
+.faqImage {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ border-radius: 12px;
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
+}
+
+.faqContentBlock {
+ display: flex;
+ flex-direction: column;
+ gap: 2rem;
+}
+
+.faqTitle {
+ font-family: var(--font-playfair);
+ font-size: 2.5rem;
+ color: #5d4037;
+ margin-bottom: 0.5rem;
+}
+
+.faqSubtitle {
+ font-family: var(--font-lato);
+ font-size: 1.1rem;
+ color: #836839;
+ line-height: 1.6;
+ margin-bottom: 1rem;
+}
+
+.faqAccordion {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+}
+
+.faqItem {
+ background: #fff;
+ border: 2px solid #C5A059;
+ border-radius: 8px;
+ overflow: hidden;
+ transition: all 0.3s ease;
+}
+
+.faqItem:hover {
+ box-shadow: 0 4px 12px rgba(197, 160, 89, 0.2);
+}
+
+.faqQuestion {
+ width: 100%;
+ padding: 1.5rem 2rem;
+ background: transparent;
+ border: none;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ cursor: pointer;
+ font-family: var(--font-lato);
+ font-size: 1.1rem;
+ font-weight: 600;
+ color: #5d4037;
+ text-align: left;
+ transition: all 0.3s ease;
+}
+
+.faqQuestion:hover {
+ background-color: #faf6f0;
+}
+
+.faqQuestionActive {
+ background-color: #C5A059;
+ color: #fff;
+}
+
+.faqIcon {
+ font-size: 1.5rem;
+ font-weight: bold;
+ color: #C5A059;
+ transition: transform 0.3s ease;
+ flex-shrink: 0;
+ margin-left: 1rem;
+}
+
+.faqQuestionActive .faqIcon {
+ color: #fff;
+ transform: rotate(180deg);
+}
+
+.faqAnswer {
+ padding: 1.5rem 2rem;
+ border-top: 1px solid #e0d5c7;
+ animation: slideDown 0.3s ease;
+}
+
+.faqAnswer p {
+ font-family: var(--font-lato);
+ font-size: 1rem;
+ color: #5d4037;
+ line-height: 1.8;
+ margin: 0;
+}
+
+@keyframes slideDown {
+ from {
+ opacity: 0;
+ transform: translateY(-10px);
+ }
+
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
+@media (max-width: 1024px) {
+ .faqContainer {
+ grid-template-columns: 1fr;
+ gap: 3rem;
+ }
+
+ .faqImageBlock {
+ min-height: 400px;
+ }
+}
+
+@media (max-width: 768px) {
+ .faqSection {
+ padding: 60px 20px;
+ }
+
+ .faqTitle {
+ font-size: 2rem;
+ }
+
+ .faqSubtitle {
+ font-size: 1rem;
+ }
+
+ .faqQuestion {
+ padding: 1.2rem 1.5rem;
+ font-size: 1rem;
+ }
+
+ .faqAnswer {
+ padding: 1.2rem 1.5rem;
+ }
+
+ .faqImageBlock {
+ min-height: 300px;
+ }
+}
\ No newline at end of file
diff --git a/src/app/about/about_temp.css b/src/app/about/about_temp.css
new file mode 100644
index 0000000..3ccf7f6
--- /dev/null
+++ b/src/app/about/about_temp.css
@@ -0,0 +1,168 @@
+.main {
+ background-color: var(--color-dark);
+ color: var(--color-text-light);
+ min-height: 100vh;
+}
+
+.hero {
+ padding: 10rem 2rem;
+ background: linear-gradient(rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.6)), url('/images/hero-1.png');
+ background-size: cover;
+ background-position: center;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ text-align: center;
+}
+
+.heroContent {
+ max-width: 800px;
+}
+
+.heroTitle {
+ font-family: var(--font-playfair);
+ font-size: 4rem;
+ color: var(--color-gold);
+ margin-bottom: 1rem;
+ text-transform: uppercase;
+ letter-spacing: 2px;
+}
+
+.breadcrumb {
+ font-size: 1.1rem;
+ color: #C5A059;
+ font-family: var(--font-lato);
+}
+
+.breadcrumb a {
+ color: #fff;
+ transition: color 0.3s;
+}
+
+.breadcrumb a:hover {
+ color: var(--color-gold);
+}
+
+.section {
+ padding: 80px 20px;
+ background-color: #f5e6d3;
+}
+
+.featuresSection {
+ background-color: #3a0c08;
+ background-image: url('/images/section-bg.jpg');
+ background-size: cover;
+ background-position: center;
+}
+
+.testimonialsSection {
+ background-color: #0a0a0a;
+}
+
+.container {
+ max-width: 1200px;
+ margin: 0 auto;
+ display: flex;
+ align-items: center;
+ gap: 4rem;
+ flex-wrap: wrap;
+}
+
+.textBlock {
+ flex: 1;
+ min-width: 300px;
+}
+
+.imageBlock {
+ flex: 1;
+ min-width: 300px;
+ display: flex;
+ justify-content: center;
+}
+
+.sectionTitle {
+ font-family: var(--font-playfair);
+ font-size: 3rem;
+ color: #C5A059;
+ margin-bottom: 1.5rem;
+ text-transform: uppercase;
+ letter-spacing: 2px;
+}
+
+.sectionTitleCenter {
+ font-family: var(--font-playfair);
+ font-size: 3.5rem;
+ color: #C5A059;
+ margin-bottom: 3rem;
+ text-align: center;
+ text-transform: uppercase;
+ letter-spacing: 2px;
+}
+
+.text {
+ font-size: 1.1rem;
+ line-height: 1.8;
+ color: #C5A059;
+ margin-bottom: 1.5rem;
+ opacity: 0.9;
+ font-family: var(--font-lato);
+}
+
+.image {
+ border-radius: 8px;
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
+ max-width: 100%;
+ height: auto;
+ border: 4px solid #C5A059;
+}
+
+.menuButton {
+ display: inline-block;
+ padding: 15px 40px;
+ border: 2px solid #C5A059;
+ color: #C5A059;
+ font-family: var(--font-lato);
+ font-size: 1.1rem;
+ text-transform: uppercase;
+ text-decoration: none;
+ transition: all 0.3s ease;
+ background: transparent;
+ letter-spacing: 1px;
+ margin-top: 1rem;
+}
+
+.menuButton:hover {
+ background-color: #C5A059;
+ color: #000;
+}
+
+/* Features Section */
+.featuresGrid {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ gap: 3rem;
+ max-width: 1200px;
+ margin: 0 auto;
+}
+
+.featureCard {
+ background-color: #F5E6D3;
+ padding: 2.5rem 2rem;
+ text-align: center;
+ border: 4px solid #C5A059;
+ transition: transform 0.3s ease;
+}
+
+.featureCard:hover {
+ transform: translateY(-10px);
+}
+
+.featureImageWrapper {
+ position: relative;
+ width: 100%;
+ height: 200px;
+ margin-bottom: 1.5rem;
+ border-radius: 8px;
+ overflow: hidden;
+ border: 2px solid #C5A059;
+}
\ No newline at end of file
diff --git a/src/app/about/page.tsx b/src/app/about/page.tsx
new file mode 100644
index 0000000..4032397
--- /dev/null
+++ b/src/app/about/page.tsx
@@ -0,0 +1,352 @@
+'use client'
+
+import Navbar from "@/components/Navbar/Navbar";
+import Footer from "@/components/Footer/Footer";
+import FAQ from "@/components/FAQ/FAQ";
+import Image from "next/image";
+import Link from "next/link";
+import styles from "./about.module.css";
+import { featuresData, testimonialData, ctaData, aboutFaqData } from "@/utils/constant";
+import { useState, useEffect } from "react";
+import { motion, AnimatePresence } from "framer-motion";
+
+export default function AboutPage() {
+ const [currentTestimonial, setCurrentTestimonial] = useState(0);
+
+ // Animation variants
+ const fadeInUp = {
+ hidden: { opacity: 0, y: 30 },
+ visible: {
+ opacity: 1,
+ y: 0,
+ transition: {
+ duration: 0.6
+ }
+ }
+ };
+
+ const fadeIn = {
+ hidden: { opacity: 0 },
+ visible: {
+ opacity: 1,
+ transition: { duration: 0.8 }
+ }
+ };
+
+ const slideInLeft = {
+ hidden: { opacity: 0, x: -50 },
+ visible: {
+ opacity: 1,
+ x: 0,
+ transition: {
+ duration: 0.7
+ }
+ }
+ };
+
+ const slideInRight = {
+ hidden: { opacity: 0, x: 50 },
+ visible: {
+ opacity: 1,
+ x: 0,
+ transition: {
+ duration: 0.7
+ }
+ }
+ };
+
+ const staggerContainer = {
+ hidden: { opacity: 0 },
+ visible: {
+ opacity: 1,
+ transition: {
+ staggerChildren: 0.2,
+ delayChildren: 0.1
+ }
+ }
+ };
+
+ // Auto-slide testimonials
+ useEffect(() => {
+ const interval = setInterval(() => {
+ setCurrentTestimonial((prev) => (prev + 1) % testimonialData.length);
+ }, 5000); // Change every 5 seconds
+
+ return () => clearInterval(interval);
+ }, []);
+
+ const nextTestimonial = () => {
+ setCurrentTestimonial((prev) => (prev + 1) % testimonialData.length);
+ };
+
+ const prevTestimonial = () => {
+ setCurrentTestimonial((prev) => (prev - 1 + testimonialData.length) % testimonialData.length);
+ };
+
+ return (
+
+
+
+ {/* Hero Banner */}
+
+
+
About Us
+
+ Home / About
+
+
+
+
+ {/* About Section - No boxed structure */}
+
+
+
+ Our Story
+
+ Founded in 2010, Antalya Restaurant began with a simple mission: to bring the authentic flavors of Turkey to our community.
+ What started as a small family-run kitchen has grown into a beloved dining destination, known for its warm hospitality and traditional recipes passed down through generations.
+
+
+ Every dish we serve tells a story of tradition, passion, and dedication to the culinary arts. Our chefs use time-honored techniques combined with the freshest ingredients to create an unforgettable dining experience.
+
+
+ View Our Menu
+
+
+
+
+
+
+
+
+ {/* Features Section - With real images */}
+
+
+ What Makes Us Special
+
+
+ {featuresData.map((feature) => (
+
+
+
+
+ {feature.title}
+ {feature.description}
+
+ ))}
+
+
+
+ {/* Why Choose Us Section */}
+
+
+
+
+
+
+ Why Choose Us
+
+ At Antalya Restaurant, we don't just serve food – we create experiences. Our commitment to authenticity means every spice, every ingredient, and every cooking method stays true to Turkish culinary traditions.
+
+
+ From our charcoal-grilled kebabs to our handmade baklava, we take pride in delivering dishes that transport you straight to the streets of Istanbul and the coasts of Antalya.
+
+
+
+
+
+ {/* Testimonials Section - Auto Slider */}
+
+
+ What Our Guests Say
+
+
+ ‹
+
+
+
+ "{testimonialData[currentTestimonial].text}"
+
+
+
+
+
+
{testimonialData[currentTestimonial].name}
+
{testimonialData[currentTestimonial].role}
+
+
+
+
+
+ ›
+
+
+ {/* Slider dots */}
+
+ {testimonialData.map((_, index) => (
+ setCurrentTestimonial(index)}
+ />
+ ))}
+
+
+
+ {/* FAQ Section - Image Left, FAQ Right */}
+
+
+
+
+
+
+ Frequently Asked Questions
+
+ Have questions about Antalya Restaurant? Find answers to our most commonly asked questions below.
+
+
+ {aboutFaqData.map((faq, index) => (
+
+ ))}
+
+
+
+
+
+ {/* Call to Action */}
+
+
+
+ {ctaData.title}
+
+
+ {ctaData.subtitle}
+
+
+
+ {ctaData.buttonText}
+
+
+
+
+
+
+
+ );
+}
+
+// FAQ Item Component
+function FaqItem({ question, answer }: { question: string; answer: string }) {
+ const [isOpen, setIsOpen] = useState(false);
+
+ return (
+
+
setIsOpen(!isOpen)}
+ >
+ {question}
+ {isOpen ? '−' : '+'}
+
+ {isOpen && (
+
+ )}
+
+ );
+}
diff --git a/src/app/blog/[id]/blogDetail.module.css b/src/app/blog/[id]/blogDetail.module.css
new file mode 100644
index 0000000..caa2590
--- /dev/null
+++ b/src/app/blog/[id]/blogDetail.module.css
@@ -0,0 +1,310 @@
+.main {
+ background-color: var(--color-dark);
+ color: var(--color-text-light);
+ min-height: 100vh;
+}
+
+.hero {
+ padding: 10rem 2rem;
+ background-size: cover;
+ background-position: center;
+ text-align: center;
+}
+
+.heroContent {
+ max-width: 800px;
+ margin: 0 auto;
+}
+
+.heroTitle {
+ font-family: var(--font-playfair);
+ font-size: 4rem;
+ color: #C5A059;
+ margin-bottom: 1rem;
+ text-transform: uppercase;
+ letter-spacing: 2px;
+}
+
+.breadcrumb {
+ font-size: 1.1rem;
+ color: #C5A059;
+ font-family: var(--font-lato);
+}
+
+.breadcrumb a {
+ color: #fff;
+ transition: color 0.3s;
+}
+
+.breadcrumb a:hover {
+ color: var(--color-gold);
+}
+
+.article {
+ background-color: #F5E6D3;
+ padding: 60px 20px;
+}
+
+.contentContainer {
+ max-width: 1200px;
+ margin: 0 auto;
+ background: #fff;
+ padding: 3rem;
+ border: 4px solid #C5A059;
+}
+
+.meta {
+ display: flex;
+ align-items: center;
+ gap: 1rem;
+ margin-bottom: 2rem;
+ flex-wrap: wrap;
+ font-family: var(--font-lato);
+}
+
+.category {
+ background: #C5A059;
+ color: #fff;
+ padding: 0.5rem 1rem;
+ border-radius: 4px;
+ font-size: 0.9rem;
+ font-weight: 600;
+ text-transform: uppercase;
+}
+
+.date,
+.comments {
+ color: #836839;
+ font-size: 0.95rem;
+}
+
+.separator {
+ color: #d4c5b0;
+}
+
+.featuredImage {
+ width: 100%;
+ height: 500px;
+ position: relative;
+ margin-bottom: 2.5rem;
+ border-radius: 8px;
+ overflow: hidden;
+ border: 3px solid #C5A059;
+}
+
+.featuredImage img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+.content {
+ font-family: var(--font-lato);
+ font-size: 1.1rem;
+ line-height: 1.8;
+ color: #5d4037;
+}
+
+.content h2 {
+ font-family: var(--font-playfair);
+ font-size: 2rem;
+ color: #5d4037;
+ margin: 2rem 0 1rem;
+ padding-bottom: 0.5rem;
+ border-bottom: 2px solid #C5A059;
+}
+
+.content h3 {
+ font-family: var(--font-playfair);
+ font-size: 1.6rem;
+ color: #5d4037;
+ margin: 1.5rem 0 1rem;
+}
+
+.content h4 {
+ font-family: var(--font-playfair);
+ font-size: 1.3rem;
+ color: #5d4037;
+ margin: 1.2rem 0 0.8rem;
+}
+
+.content p {
+ margin-bottom: 1.2rem;
+}
+
+.content ul {
+ margin: 1.5rem 0;
+ padding-left: 2rem;
+}
+
+.content li {
+ margin-bottom: 0.8rem;
+ color: #5d4037;
+}
+
+.content strong {
+ color: #3e2723;
+ font-weight: 600;
+}
+
+.content a {
+ color: #C5A059;
+ text-decoration: underline;
+ transition: color 0.3s;
+}
+
+.content a:hover {
+ color: #b08f4a;
+}
+
+.content .sec-title {
+ margin-top: 2rem;
+}
+
+.content .mt-4 {
+ margin-top: 1.5rem;
+}
+
+.content .list-style-two {
+ list-style: none;
+ padding-left: 0;
+}
+
+.content .list-style-two li {
+ position: relative;
+ padding-left: 2rem;
+}
+
+.content .list-style-two li:before {
+ content: "✓";
+ position: absolute;
+ left: 0;
+ color: #C5A059;
+ font-weight: bold;
+ font-size: 1.2rem;
+}
+
+/* Impressive Blockquote Styling */
+.content blockquote {
+ text-align: center;
+ background: linear-gradient(135deg, #faf6f0 0%, #f5ede0 100%);
+ border-left: 6px solid #c5a059;
+ /* border-right: 6px solid #c5a059; */
+ /* max-width: 800px; */
+ margin: 3rem 0px;
+ padding: 10px 20px 10px 20px;
+ position: relative;
+ box-shadow: 0 8px 24px #c5a05926;
+}
+
+.content blockquote p {
+ font-family: var(--font-playfair);
+ font-size: 1.4rem;
+ font-style: italic;
+ color: #5d4037;
+ line-height: 1.8;
+ margin: 0;
+ position: relative;
+ z-index: 1;
+}
+
+.content blockquote cite {
+ display: block;
+ margin-top: 1.5rem;
+ font-family: var(--font-lato);
+ font-size: 1rem;
+ font-style: normal;
+ color: #C5A059;
+ font-weight: 600;
+}
+
+.content blockquote cite:before {
+ content: "— ";
+}
+
+.navigation {
+ margin-top: 3rem;
+ padding-top: 2rem;
+ border-top: 2px solid #e0d5c7;
+}
+
+.backButton {
+ display: inline-block;
+ padding: 12px 30px;
+ background: transparent;
+ border: 2px solid #C5A059;
+ color: #C5A059;
+ font-family: var(--font-lato);
+ font-size: 1rem;
+ font-weight: 600;
+ text-decoration: none;
+ transition: all 0.3s;
+ text-transform: uppercase;
+ letter-spacing: 1px;
+}
+
+.backButton:hover {
+ background: #C5A059;
+ color: #fff;
+}
+
+.errorContainer {
+ min-height: 60vh;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ padding: 4rem 2rem;
+}
+
+.errorTitle {
+ font-family: var(--font-playfair);
+ font-size: 3rem;
+ color: #C5A059;
+ margin-bottom: 2rem;
+}
+
+.backLink {
+ color: #C5A059;
+ font-size: 1.2rem;
+ text-decoration: underline;
+}
+
+@media (max-width: 768px) {
+ .heroTitle {
+ font-size: 2.5rem;
+ }
+
+ .contentContainer {
+ padding: 2rem 1.5rem;
+ }
+
+ .featuredImage {
+ height: 300px;
+ }
+
+ .content {
+ font-size: 1rem;
+ }
+
+ .content h2 {
+ font-size: 1.6rem;
+ }
+
+ .content h3 {
+ font-size: 1.3rem;
+ }
+
+ .content blockquote {
+ padding: 2rem 2rem;
+ margin: 2rem auto;
+ }
+
+ .content blockquote p {
+ font-size: 1.2rem;
+ }
+
+ .meta {
+ font-size: 0.85rem;
+ }
+}
\ No newline at end of file
diff --git a/src/app/blog/[id]/page.tsx b/src/app/blog/[id]/page.tsx
new file mode 100644
index 0000000..a6070f8
--- /dev/null
+++ b/src/app/blog/[id]/page.tsx
@@ -0,0 +1,94 @@
+'use client'
+
+import { useParams } from 'next/navigation';
+import Navbar from "@/components/Navbar/Navbar";
+import Footer from "@/components/Footer/Footer";
+import FAQ from "@/components/FAQ/FAQ";
+import Image from "next/image";
+import Link from "next/link";
+import styles from "./blogDetail.module.css";
+import { blogData } from "@/utils/constant";
+
+export default function BlogDetailPage() {
+ const params = useParams();
+ const slug = params.id as string;
+ const blog = blogData.find((b) => b.slug === slug);
+
+ if (!blog) {
+ return (
+
+
+
+
Blog Post Not Found
+ Back to Blog
+
+
+
+ );
+ }
+
+ return (
+
+
+
+ {/* Banner Section */}
+
+
+
{blog.title}
+
+ Home / Blog / {blog.title}
+
+
+
+
+ {/* Blog Content */}
+
+
+ {/* Meta Information */}
+
+ {/* Featured Image */}
+ {blog.detailImage && (
+
+
+
+ )}
+
+
+ {blog.category}
+ |
+ {blog.date}
+ |
+ {blog.comments}
+
+
+
+ {/* Blog Content */}
+
+
+ {/* FAQ Section */}
+ {blog.faqs && blog.faqs.length > 0 && (
+
+ )}
+
+
+ {/* Navigation */}
+
+ ← Back to All Blogs
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/app/blog/blog.module.css b/src/app/blog/blog.module.css
new file mode 100644
index 0000000..6646cb1
--- /dev/null
+++ b/src/app/blog/blog.module.css
@@ -0,0 +1,143 @@
+.main {
+ background-color: var(--color-dark);
+ color: var(--color-text-light);
+ min-height: 100vh;
+ background-color: #f5e6d3;
+}
+
+.hero {
+ padding: 10rem 2rem;
+ background: linear-gradient(rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.6)), url('/images/dish-2.png');
+ background-size: cover;
+ background-position: center;
+ text-align: center;
+}
+
+.heroContent {
+ max-width: 800px;
+ margin: 0 auto;
+}
+
+.heroTitle {
+ font-family: var(--font-playfair);
+ font-size: 4rem;
+ color: #C5A059;
+ margin-bottom: 1rem;
+ text-transform: uppercase;
+ letter-spacing: 2px;
+}
+
+.breadcrumb {
+ font-size: 1.1rem;
+ color: #C5A059;
+ font-family: var(--font-lato);
+}
+
+.breadcrumb a {
+ color: #fff;
+ transition: color 0.3s;
+}
+
+.breadcrumb a:hover {
+ color: var(--color-gold);
+}
+
+.blogSection {
+ padding: 80px 20px;
+ max-width: 1200px;
+ margin: 0 auto;
+ /* background-color: #0a0a0a; */
+}
+
+.grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
+ gap: 2rem;
+}
+
+.card {
+ background-color: #F5E6D3;
+ border: 4px solid #C5A059;
+ overflow: hidden;
+ transition: transform 0.3s ease, box-shadow 0.3s ease;
+}
+
+.card:hover {
+ transform: translateY(-10px);
+ box-shadow: 0 10px 30px rgba(197, 160, 89, 0.5);
+}
+
+.imageContainer {
+ position: relative;
+ width: 100%;
+ height: 250px;
+ border-bottom: 1px solid #C5A059;
+}
+
+.cardContent {
+ padding: 1.5rem;
+ display: flex;
+ flex-direction: column;
+ height: calc(100% - 250px);
+}
+
+.blogTitle {
+ font-family: var(--font-playfair);
+ font-size: 1.6rem;
+ margin-bottom: 0.5rem;
+}
+
+.blogTitle a {
+ color: #3e2723;
+ transition: color 0.3s;
+}
+
+.blogTitle a:hover {
+ color: #C5A059;
+}
+
+.date {
+ font-size: 0.9rem;
+ color: #836839;
+ margin-bottom: 1rem;
+ font-family: var(--font-lato);
+ font-weight: 600;
+}
+
+.excerpt {
+ font-size: 1rem;
+ color: #5d4037;
+ line-height: 1.6;
+ margin-bottom: 1.5rem;
+ flex-grow: 1;
+ font-family: var(--font-lato);
+}
+
+.button {
+ display: inline-block;
+ padding: 10px 25px;
+ border: 2px solid #C5A059;
+ color: #5d4037;
+ text-align: center;
+ transition: all 0.3s ease;
+ align-self: flex-start;
+ font-family: var(--font-lato);
+ text-transform: uppercase;
+ font-size: 0.85rem;
+ font-weight: 600;
+}
+
+.button:hover {
+ background-color: #C5A059;
+ color: #fff;
+}
+
+@media (max-width: 768px) {
+ .heroTitle {
+ font-size: 3rem;
+ }
+
+ .blogSection {
+ padding: 60px 20px;
+ }
+}
\ No newline at end of file
diff --git a/src/app/blog/page.tsx b/src/app/blog/page.tsx
new file mode 100644
index 0000000..5749e18
--- /dev/null
+++ b/src/app/blog/page.tsx
@@ -0,0 +1,110 @@
+'use client'
+
+import Navbar from "@/components/Navbar/Navbar";
+import Footer from "@/components/Footer/Footer";
+import Image from "next/image";
+import Link from "next/link";
+import styles from "./blog.module.css";
+import { blogData } from "@/utils/constant";
+import { motion } from "framer-motion";
+
+export default function BlogPage() {
+ // Animation variants
+ const containerVariants = {
+ hidden: { opacity: 0 },
+ visible: {
+ opacity: 1,
+ transition: {
+ staggerChildren: 0.15,
+ delayChildren: 0.2
+ }
+ }
+ };
+
+ const cardVariants = {
+ hidden: {
+ opacity: 0,
+ y: 30
+ },
+ visible: {
+ opacity: 1,
+ y: 0,
+ transition: {
+ duration: 0.6
+ }
+ }
+ };
+
+ const heroVariants = {
+ hidden: { opacity: 0, y: -20 },
+ visible: {
+ opacity: 1,
+ y: 0,
+ transition: {
+ duration: 0.8
+ }
+ }
+ };
+
+ return (
+
+
+
+
+
+
Our Blog
+
+ Home / Blog
+
+
+
+
+
+
+ {blogData.map((blog) => (
+
+
+
+
+
+
+ {blog.title}
+
+
{blog.date}
+
{blog.excerpt}
+
+ Read More
+
+
+
+ ))}
+
+
+
+
+
+ );
+}
diff --git a/src/app/contact/contact.module.css b/src/app/contact/contact.module.css
new file mode 100644
index 0000000..cf7343e
--- /dev/null
+++ b/src/app/contact/contact.module.css
@@ -0,0 +1,315 @@
+.main {
+ background-color: var(--color-dark);
+ color: var(--color-text-light);
+ min-height: 100vh;
+}
+
+.hero {
+ padding: 10rem 2rem;
+ background: linear-gradient(rgba(0, 0, 0, 0.7), rgba(0, 0, 0, 0.7)), url('/images/hero-2.png');
+ background-size: cover;
+ background-position: center;
+ text-align: center;
+}
+
+.heroContent {
+ max-width: 800px;
+ margin: 0 auto;
+}
+
+.heroTitle {
+ font-family: var(--font-playfair);
+ font-size: 4rem;
+ color: #C5A059;
+ margin-bottom: 1rem;
+ text-transform: uppercase;
+ letter-spacing: 2px;
+}
+
+.breadcrumb {
+ font-size: 1.1rem;
+ color: #C5A059;
+ font-family: var(--font-lato);
+}
+
+.breadcrumb a {
+ color: #fff;
+ transition: color 0.3s;
+}
+
+.breadcrumb a:hover {
+ color: var(--color-gold);
+}
+
+.contactSection {
+ padding: 80px 20px;
+ background-color: #F5E6D3;
+ /* background-image: url('/images/section-bg.jpg'); */
+ background-size: cover;
+ background-position: center;
+}
+
+.container {
+ max-width: 1400px;
+ margin: 0 auto;
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 4rem;
+}
+
+/* Left Side - Form Block */
+.formBlock {
+ background-color: #F5E6D3;
+ padding: 2.5rem;
+ border: 4px solid #C5A059;
+}
+
+.title {
+ font-family: var(--font-cinzel), serif;
+ font-size: 2.5rem;
+ color: #5d4037;
+ margin-bottom: 1rem;
+ font-weight: 600;
+ border-bottom: 3px solid #C5A059;
+ padding-bottom: 0.5rem;
+ display: inline-block;
+}
+
+.subtitle {
+ font-size: 1rem;
+ color: #5d4037;
+ line-height: 1.6;
+ margin-bottom: 2rem;
+ font-family: var(--font-lato);
+}
+
+.form {
+ display: flex;
+ flex-direction: column;
+ gap: 1.5rem;
+}
+
+.formRow {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 1.5rem;
+}
+
+.formGroup {
+ display: flex;
+ flex-direction: column;
+ gap: 0.5rem;
+}
+
+.formLabel {
+ font-family: var(--font-lato);
+ color: #C5A059;
+ font-size: 0.95rem;
+ font-weight: 600;
+}
+
+.input,
+.textarea {
+ background: #fff;
+ border: 1px solid #d4c5b0;
+ padding: 0.9rem;
+ color: #C5A059;
+ font-family: var(--font-lato);
+ font-size: 0.95rem;
+ transition: border-color 0.3s;
+ border-radius: 4px;
+}
+
+.input::placeholder,
+.textarea::placeholder {
+ color: #a89b87;
+}
+
+.input:focus,
+.textarea:focus {
+ outline: none;
+ border-color: #C5A059;
+}
+
+.textarea {
+ resize: vertical;
+ min-height: 100px;
+}
+
+.charCount {
+ font-size: 0.85rem;
+ color: #836839;
+ text-align: right;
+ font-family: var(--font-lato);
+}
+
+.submitButton {
+ background: #C5A059;
+ border: none;
+ color: #fff;
+ padding: 15px 40px;
+ font-size: 1rem;
+ font-weight: 600;
+ cursor: pointer;
+ transition: all 0.3s;
+ text-transform: uppercase;
+ letter-spacing: 1px;
+ font-family: var(--font-lato);
+ border-radius: 50px;
+ margin-top: 1rem;
+}
+
+.submitButton:hover {
+ background-color: #b08f4a;
+ transform: translateY(-2px);
+ box-shadow: 0 4px 12px rgba(197, 160, 89, 0.3);
+}
+
+/* Alert Messages */
+.alert {
+ padding: 1rem 1.5rem;
+ border-radius: 8px;
+ margin-bottom: 1.5rem;
+ font-family: var(--font-lato);
+ font-size: 0.95rem;
+}
+
+.alertSuccess {
+ background-color: #d4edda;
+ color: #155724;
+ border: 1px solid #c3e6cb;
+}
+
+.alertDanger {
+ background-color: #f8d7da;
+ color: #721c24;
+ border: 1px solid #f5c6cb;
+}
+
+.errorText {
+ color: #dc3545;
+ font-size: 0.85rem;
+ margin-top: 0.25rem;
+ display: block;
+ font-family: var(--font-lato);
+}
+
+.recaptchaWrapper {
+ margin: 1rem 0;
+}
+
+/* Right Side - Info Block */
+.infoBlock {
+ display: flex;
+ flex-direction: column;
+ gap: 1.5rem;
+}
+
+.locationCard {
+ background: #F5E6D3;
+ padding: 1.5rem;
+ border: 4px solid #C5A059;
+ display: flex;
+ align-items: flex-start;
+ gap: 1.5rem;
+ transition: transform 0.3s;
+}
+
+.locationCard:hover {
+ transform: translateY(-5px);
+}
+
+.iconWrapper {
+ background: #C5A059;
+ width: 50px;
+ height: 50px;
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-shrink: 0;
+}
+
+.icon {
+ width: 24px;
+ height: 24px;
+ color: #fff;
+}
+
+.locationInfo {
+ flex: 1;
+}
+
+.locationTitle {
+ font-family: var(--font-cinzel), serif;
+ font-size: 1.3rem;
+ color: #5d4037;
+ margin-bottom: 0.3rem;
+ font-weight: 600;
+}
+
+.locationSubtitle {
+ font-size: 0.9rem;
+ color: #836839;
+ margin-bottom: 0.5rem;
+ font-family: var(--font-lato);
+}
+
+.locationAddress,
+.locationPhone {
+ font-size: 1rem;
+ color: #5d4037;
+ line-height: 1.6;
+ font-family: var(--font-lato);
+}
+
+.locationPhone {
+ font-size: 1.2rem;
+ font-weight: 600;
+ color: #C5A059;
+}
+
+.mapContainer {
+ border: 4px solid #C5A059;
+ overflow: hidden;
+ margin-top: 0.5rem;
+}
+
+.mapContainer iframe {
+ display: block;
+ width: 100%;
+ height: 300px;
+}
+
+@media (max-width: 1024px) {
+ .container {
+ grid-template-columns: 1fr;
+ gap: 3rem;
+ }
+
+ .formRow {
+ grid-template-columns: 1fr;
+ }
+}
+
+@media (max-width: 768px) {
+ .heroTitle {
+ font-size: 3rem;
+ }
+
+ .contactSection {
+ padding: 60px 20px;
+ }
+
+ .title {
+ font-size: 2rem;
+ }
+
+ .formRow {
+ grid-template-columns: 1fr;
+ }
+
+ .formBlock {
+ padding: 2rem 1.5rem;
+ }
+}
\ No newline at end of file
diff --git a/src/app/contact/page.tsx b/src/app/contact/page.tsx
new file mode 100644
index 0000000..5b60a10
--- /dev/null
+++ b/src/app/contact/page.tsx
@@ -0,0 +1,384 @@
+'use client'
+
+import { useState, useEffect } from "react";
+import ReCAPTCHA from "react-google-recaptcha";
+import axios from "axios";
+import Navbar from "@/components/Navbar/Navbar";
+import Footer from "@/components/Footer/Footer";
+import Link from "next/link";
+import styles from "./contact.module.css";
+import { motion } from "framer-motion";
+
+interface FormErrors {
+ name?: string;
+ email?: string;
+ phone?: string;
+ date?: string;
+ time?: string;
+ captcha?: string;
+}
+
+export default function ContactPage() {
+ const [email, setEmail] = useState("");
+
+ useEffect(() => {
+ const user = "info";
+ const domain = "antalya-restaurant.com";
+ setEmail(`${user}@${domain}`);
+ }, []);
+
+ const [formData, setFormData] = useState({
+ name: "",
+ email: "",
+ phone: "",
+ guests: "2 Guests",
+ date: "",
+ time: "",
+ requests: "",
+ });
+
+ const [formErrors, setFormErrors] = useState({});
+ const [captchaToken, setCaptchaToken] = useState(null);
+ const [alert, setAlert] = useState({ show: false, type: "", message: "" });
+ const [charCount, setCharCount] = useState(0);
+
+ const handleChange = (e: React.ChangeEvent) => {
+ const { name, value } = e.target;
+ setFormData((prev) => ({ ...prev, [name]: value }));
+
+ if (name === "requests") {
+ setCharCount(value.length);
+ }
+ };
+
+ const handleCaptchaChange = (token: string | null) => {
+ setCaptchaToken(token);
+ };
+
+ const handleSubmit = async (e: React.FormEvent) => {
+ e.preventDefault();
+
+ const errors: FormErrors = {};
+ if (!formData.name.trim()) errors.name = "Name is required.";
+ if (!formData.email.trim()) errors.email = "Email is required.";
+ if (!formData.phone.trim()) errors.phone = "Phone is required.";
+ if (!formData.date.trim()) errors.date = "Date is required.";
+ if (!formData.time.trim()) errors.time = "Time is required.";
+ if (!captchaToken) errors.captcha = "Please verify the CAPTCHA.";
+
+ setFormErrors(errors);
+ if (Object.keys(errors).length > 0) return;
+
+ const emailData = {
+ name: formData.name,
+ phone: formData.phone,
+ email: formData.email,
+ subject: `Table Reservation - ${formData.guests} on ${formData.date}`,
+ message: `
+ Reservation Details:
+ Name: ${formData.name}
+ Email: ${formData.email}
+ Phone: ${formData.phone}
+ Guests: ${formData.guests}
+ Date: ${formData.date}
+ Time: ${formData.time}
+ Special Requests:
+ ${formData.requests || "None"}
+ `,
+ to: email,
+ senderName: "Antalya Restaurant - Table Reservation",
+ recaptchaToken: captchaToken,
+ };
+
+ try {
+ const res = await axios.post(
+ "https://mailserver.metatronnest.com/send",
+ emailData,
+ { headers: { "Content-Type": "application/json" } }
+ );
+
+ setAlert({
+ show: true,
+ type: "success",
+ message: res?.data?.message || "Reservation request sent successfully! We'll contact you soon.",
+ });
+
+ setFormData({
+ name: "",
+ email: "",
+ phone: "",
+ guests: "2 Guests",
+ date: "",
+ time: "",
+ requests: "",
+ });
+ setCaptchaToken(null);
+ setFormErrors({});
+ setCharCount(0);
+ } catch (error) {
+ setAlert({
+ show: true,
+ type: "danger",
+ message: "Failed to send reservation request. Please try again later.",
+ });
+ }
+ };
+
+ useEffect(() => {
+ if (alert.show) {
+ const timer = setTimeout(() => {
+ setAlert((prev) => ({ ...prev, show: false }));
+ }, 5000);
+ return () => clearTimeout(timer);
+ }
+ }, [alert.show]);
+
+ return (
+
+
+
+
+
+
Contact Us
+
+ Home / Contact
+
+
+
+
+
+
+ {/* Left Side - Book a Table Form */}
+
+ Book a Table
+
+ Reserve your table for an unforgettable Turkish dining experience. We look forward to serving you our authentic cuisine.
+
+
+ {alert.show && (
+
+ {alert.message}
+
+ )}
+
+
+
+
+ {/* Right Side - Location Info & Map */}
+
+ {/* Location Cards */}
+
+
+
+
Kitchener Location
+
Main Restaurant
+
+ 1187 Fischer-Hallman Rd #411
+ Kitchener, ON N2T 4H2
+
+
+
+
+
+
+
+
Burlington Location
+
Second Location
+
+ 1860 Appleby Line
+ Burlington, ON L7L 7H7
+
+
+
+
+
+
+
+
Call Us
+
For reservations & inquiries
+
(519) 570-4848
+
+
+
+ {/* Map */}
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/app/gallery/gallery.module.css b/src/app/gallery/gallery.module.css
new file mode 100644
index 0000000..0757f6a
--- /dev/null
+++ b/src/app/gallery/gallery.module.css
@@ -0,0 +1,219 @@
+.main {
+ background-color: var(--color-dark);
+ color: var(--color-text-light);
+ min-height: 100vh;
+ background-color: #f5e6d3;
+}
+
+.hero {
+ padding: 10rem 2rem;
+ background: linear-gradient(rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.6)), url('/images/hero-2.png');
+ background-size: cover;
+ background-position: center;
+ text-align: center;
+}
+
+.heroContent {
+ max-width: 800px;
+ margin: 0 auto;
+}
+
+.heroTitle {
+ font-family: var(--font-playfair);
+ font-size: 4rem;
+ color: #C5A059;
+ margin-bottom: 1rem;
+ text-transform: uppercase;
+ letter-spacing: 2px;
+}
+
+.breadcrumb {
+ font-size: 1.1rem;
+ color: #C5A059;
+ font-family: var(--font-lato);
+}
+
+.breadcrumb a {
+ color: #fff;
+ transition: color 0.3s;
+}
+
+.breadcrumb a:hover {
+ color: var(--color-gold);
+}
+
+.section {
+ padding: 80px 20px;
+ max-width: 1200px;
+ margin: 0 auto;
+ /* background-color: #0a0a0a; */
+}
+
+.tabs {
+ display: flex;
+ justify-content: center;
+ gap: 1.5rem;
+ margin-bottom: 3rem;
+}
+
+.tab {
+ background: transparent;
+ border: 2px solid #C5A059;
+ color: #C5A059;
+ padding: 12px 30px;
+ font-size: 1rem;
+ cursor: pointer;
+ transition: all 0.3s ease;
+ font-family: var(--font-lato);
+ text-transform: uppercase;
+ letter-spacing: 1px;
+ font-weight: 600;
+}
+
+.tab:hover,
+.activeTab {
+ background-color: #C5A059;
+ color: #F5E6D3;
+}
+
+.grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
+ gap: 1.5rem;
+}
+
+.imageWrapper {
+ position: relative;
+ aspect-ratio: 4/3;
+ cursor: pointer;
+ overflow: hidden;
+ border: 4px solid #C5A059;
+}
+
+.image {
+ object-fit: cover;
+ transition: transform 0.5s ease;
+}
+
+.imageWrapper:hover .image {
+ transform: scale(1.1);
+}
+
+.overlay {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background: rgba(58, 12, 8, 0.7);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ opacity: 0;
+ transition: opacity 0.3s ease;
+}
+
+.imageWrapper:hover .overlay {
+ opacity: 1;
+}
+
+.viewText {
+ color: #C5A059;
+ font-size: 1.2rem;
+ border: 2px solid #C5A059;
+ padding: 0.5rem 1.5rem;
+ font-family: var(--font-lato);
+ text-transform: uppercase;
+ letter-spacing: 1px;
+}
+
+/* Lightbox */
+.lightbox {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background: rgba(0, 0, 0, 0.95);
+ z-index: 1000;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.lightboxContent {
+ position: relative;
+ width: 90%;
+ height: 80%;
+ max-width: 1000px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.lightboxImageWrapper {
+ position: relative;
+ width: 100%;
+ height: 100%;
+}
+
+.closeBtn {
+ position: absolute;
+ top: -40px;
+ right: 0;
+ background: none;
+ border: none;
+ color: #C5A059;
+ font-size: 2.5rem;
+ cursor: pointer;
+ transition: color 0.3s;
+}
+
+.closeBtn:hover {
+ color: #fff;
+}
+
+.navBtn {
+ position: absolute;
+ top: 50%;
+ transform: translateY(-50%);
+ background: rgba(197, 160, 89, 0.2);
+ border: 2px solid #C5A059;
+ color: #C5A059;
+ font-size: 2rem;
+ padding: 1rem;
+ cursor: pointer;
+ z-index: 10;
+ transition: all 0.3s;
+}
+
+.navBtn:hover {
+ background: rgba(197, 160, 89, 0.5);
+ color: #fff;
+}
+
+.prevBtn {
+ left: -60px;
+}
+
+.nextBtn {
+ right: -60px;
+}
+
+@media (max-width: 768px) {
+ .heroTitle {
+ font-size: 3rem;
+ }
+
+ .prevBtn {
+ left: 10px;
+ }
+
+ .nextBtn {
+ right: 10px;
+ }
+
+ .tabs {
+ flex-wrap: wrap;
+ }
+}
\ No newline at end of file
diff --git a/src/app/gallery/page.tsx b/src/app/gallery/page.tsx
new file mode 100644
index 0000000..4cb4c09
--- /dev/null
+++ b/src/app/gallery/page.tsx
@@ -0,0 +1,209 @@
+'use client'
+
+import { useState } from 'react';
+import Navbar from "@/components/Navbar/Navbar";
+import Footer from "@/components/Footer/Footer";
+import Image from "next/image";
+import Link from "next/link";
+import styles from "./gallery.module.css";
+import { galleryData } from "@/utils/constant";
+import { motion, AnimatePresence } from "framer-motion";
+
+const categories = ['All', 'Food', 'Interior'];
+
+export default function GalleryPage() {
+ const [activeTab, setActiveTab] = useState('All');
+ const [lightboxOpen, setLightboxOpen] = useState(false);
+ const [currentIndex, setCurrentIndex] = useState(0);
+
+ // Animation variants
+ const heroVariants = {
+ hidden: { opacity: 0, y: -20 },
+ visible: {
+ opacity: 1,
+ y: 0,
+ transition: { duration: 0.8 }
+ }
+ };
+
+ const tabsVariants = {
+ hidden: { opacity: 0, y: 20 },
+ visible: {
+ opacity: 1,
+ y: 0,
+ transition: {
+ duration: 0.6,
+ staggerChildren: 0.1
+ }
+ }
+ };
+
+ const tabVariants = {
+ hidden: { opacity: 0, y: 10 },
+ visible: {
+ opacity: 1,
+ y: 0,
+ transition: { duration: 0.4 }
+ }
+ };
+
+ const gridVariants = {
+ hidden: { opacity: 0 },
+ visible: {
+ opacity: 1,
+ transition: {
+ staggerChildren: 0.08,
+ delayChildren: 0.1
+ }
+ }
+ };
+
+ const imageVariants = {
+ hidden: { opacity: 0, scale: 0.9 },
+ visible: {
+ opacity: 1,
+ scale: 1,
+ transition: { duration: 0.5 }
+ }
+ };
+
+ const filteredImages = activeTab === 'All'
+ ? galleryData
+ : galleryData.filter(img => img.category === activeTab);
+
+ const openLightbox = (index: number) => {
+ setCurrentIndex(index);
+ setLightboxOpen(true);
+ };
+
+ const closeLightbox = () => {
+ setLightboxOpen(false);
+ };
+
+ const nextImage = (e: React.MouseEvent) => {
+ e.stopPropagation();
+ setCurrentIndex((prev) => (prev + 1) % filteredImages.length);
+ };
+
+ const prevImage = (e: React.MouseEvent) => {
+ e.stopPropagation();
+ setCurrentIndex((prev) => (prev - 1 + filteredImages.length) % filteredImages.length);
+ };
+
+ return (
+
+
+
+
+
+
Our Gallery
+
+ Home / Gallery
+
+
+
+
+
+
+ {categories.map(category => (
+ setActiveTab(category)}
+ variants={tabVariants}
+ whileHover={{ scale: 1.05 }}
+ whileTap={{ scale: 0.95 }}
+ >
+ {category}
+
+ ))}
+
+
+
+ {filteredImages.map((img, index) => (
+ openLightbox(index)}
+ variants={imageVariants}
+ whileHover={{
+ scale: 1.05,
+ transition: { duration: 0.3 }
+ }}
+ >
+
+
+ View
+
+
+ ))}
+
+
+
+
+ {lightboxOpen && (
+
+ e.stopPropagation()}
+ initial={{ scale: 0.8, opacity: 0 }}
+ animate={{ scale: 1, opacity: 1 }}
+ exit={{ scale: 0.8, opacity: 0 }}
+ transition={{ duration: 0.3 }}
+ >
+ ×
+ ‹
+
+
+
+ ›
+
+
+ )}
+
+
+
+
+ );
+}
diff --git a/src/app/globals.css b/src/app/globals.css
index 3f92fd7..76f17bd 100644
--- a/src/app/globals.css
+++ b/src/app/globals.css
@@ -1,10 +1,11 @@
:root {
- --color-gold: #bf9b30;
+ --color-gold: #b28839;
--color-dark: #0a0a0a;
--color-input-bg: #e8e0d5;
--color-text-light: #f5f5f5;
--font-playfair: 'Playfair Display', serif;
--font-lato: 'Lato', sans-serif;
+ --font-cormorant: 'Cormorant Garamond', serif;
}
* {
@@ -19,7 +20,8 @@ body {
overflow-x: hidden;
background-color: var(--color-dark);
color: var(--color-text-light);
- font-family: var(--font-lato);
+ font-family: var(--font-cormorant);
+ font-weight: 300;
/* Ensure default font is applied */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index 5ea6e36..acd0b0f 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -1,5 +1,5 @@
import type { Metadata } from "next";
-import { Playfair_Display, Lato, Cinzel, Inter } from "next/font/google";
+import { Playfair_Display, Lato, Cinzel, Inter, Cormorant_Garamond } from "next/font/google";
import "./globals.css";
import ScrollToTop from "@/components/ScrollToTop/ScrollToTop";
@@ -28,6 +28,13 @@ const inter = Inter({
display: "swap",
});
+const cormorantGaramond = Cormorant_Garamond({
+ weight: ["300", "400"],
+ subsets: ["latin"],
+ variable: "--font-cormorant",
+ display: "swap",
+});
+
export const metadata: Metadata = {
title: "Antalya Restaurant - Book A Table",
description: "Experience luxury dining at Antalya Restaurant.",
@@ -41,8 +48,8 @@ export default function RootLayout({
children: React.ReactNode
}) {
return (
-
-
+
+
{children}
diff --git a/src/app/menu/menu.module.css b/src/app/menu/menu.module.css
new file mode 100644
index 0000000..eb10222
--- /dev/null
+++ b/src/app/menu/menu.module.css
@@ -0,0 +1,289 @@
+.main {
+ background-color: var(--color-dark);
+ color: var(--color-text-light);
+ min-height: 100vh;
+ background-color: #f5e6d3;
+}
+
+.hero {
+ padding: 10rem 2rem;
+ background: linear-gradient(rgba(0, 0, 0, 0.7), rgba(0, 0, 0, 0.7)), url('/images/hero-3.png');
+ background-size: cover;
+ background-position: center;
+ background-attachment: fixed;
+ text-align: center;
+}
+
+.heroContent {
+ max-width: 800px;
+ margin: 0 auto;
+}
+
+.heroTitle {
+ font-family: var(--font-playfair);
+ font-size: 4rem;
+ color: #C5A059;
+ margin-bottom: 1rem;
+ text-transform: uppercase;
+ letter-spacing: 2px;
+}
+
+.breadcrumb {
+ font-size: 1.1rem;
+ color: #C5A059;
+ font-family: var(--font-lato);
+}
+
+.breadcrumb a {
+ color: #fff;
+ transition: color 0.3s;
+}
+
+.breadcrumb a:hover {
+ color: var(--color-gold);
+}
+
+.menuSection {
+ max-width: 1200px;
+ margin: 0 auto;
+ padding: 60px 20px 80px;
+ /* background-color: #0a0a0a; */
+}
+
+/* Category Tabs */
+.tabs {
+ display: flex;
+ justify-content: center;
+ gap: 1.5rem;
+ margin-bottom: 3rem;
+ flex-wrap: wrap;
+}
+
+.tab {
+ background: transparent;
+ border: 2px solid #C5A059;
+ color: #C5A059;
+ padding: 12px 30px;
+ font-size: 1rem;
+ cursor: pointer;
+ transition: all 0.3s ease;
+ font-family: var(--font-playfair);
+ text-transform: uppercase;
+ letter-spacing: 1px;
+ font-weight: 600;
+}
+
+.tab:hover,
+.activeTab {
+ background-color: #C5A059;
+ color: #F5E6D3;
+ transform: translateY(-2px);
+}
+
+.menuGrid {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ gap: 2rem;
+}
+
+.menuCard {
+ display: flex;
+ gap: 1.2rem;
+ background: #c5a059;
+ padding: 1.2rem;
+ border: 1px solid rgba(197, 160, 89, 0.2);
+ transition: all 0.4s ease;
+ animation: fadeInUp 0.6s ease forwards;
+ opacity: 0;
+}
+
+.menuCard:nth-child(1) {
+ animation-delay: 0.1s;
+}
+
+.menuCard:nth-child(2) {
+ animation-delay: 0.2s;
+}
+
+.menuCard:nth-child(3) {
+ animation-delay: 0.3s;
+}
+
+.menuCard:nth-child(4) {
+ animation-delay: 0.4s;
+}
+
+.menuCard:nth-child(5) {
+ animation-delay: 0.5s;
+}
+
+.menuCard:nth-child(6) {
+ animation-delay: 0.6s;
+}
+
+@keyframes fadeInUp {
+ from {
+ opacity: 0;
+ transform: translateY(30px);
+ }
+
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
+.menuCard:hover {
+ background: #c5a059;
+ border-color: #F5E6D3;
+ transform: translateY(-5px);
+ box-shadow: 0 10px 30px rgba(197, 160, 89, 0.2);
+}
+
+.imageFrame {
+ position: relative;
+ width: 130px;
+ height: 130px;
+ flex-shrink: 0;
+ padding: 6px;
+ background: linear-gradient(135deg, rgba(197, 160, 89, 0.1), rgba(197, 160, 89, 0.05));
+}
+
+.imageWrapper {
+ position: relative;
+ width: 100%;
+ height: 100%;
+ border: 2px solid #F5E6D3;
+ overflow: hidden;
+}
+
+.dishImage {
+ object-fit: cover;
+ transition: transform 0.5s ease;
+}
+
+.menuCard:hover .dishImage {
+ transform: scale(1.1);
+}
+
+/* Corner decorations */
+.cornerTL,
+.cornerTR,
+.cornerBL,
+.cornerBR {
+ position: absolute;
+ width: 15px;
+ height: 15px;
+ border: 2px solid #F5E6D3;
+}
+
+.cornerTL {
+ top: 0;
+ left: 0;
+ border-right: none;
+ border-bottom: none;
+}
+
+.cornerTR {
+ top: 0;
+ right: 0;
+ border-left: none;
+ border-bottom: none;
+}
+
+.cornerBL {
+ bottom: 0;
+ left: 0;
+ border-right: none;
+ border-top: none;
+}
+
+.cornerBR {
+ bottom: 0;
+ right: 0;
+ border-left: none;
+ border-top: none;
+}
+
+.cardContent {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+}
+
+.cardHeader {
+ display: flex;
+ justify-content: space-between;
+ align-items: baseline;
+ margin-bottom: 0.6rem;
+}
+
+.dishName {
+ font-family: var(--font-playfair);
+ font-size: 1.3rem;
+ color: #F5E6D3;
+ text-transform: capitalize;
+ transition: color 0.3s;
+}
+
+.menuCard:hover .dishName {
+ color: #F5E6D3;
+}
+
+.price {
+ font-size: 1.2rem;
+ color: #F5E6D3;
+ font-weight: bold;
+ font-family: var(--font-playfair);
+}
+
+.description {
+ font-size: 0.9rem;
+ color: #F5E6D3;
+ line-height: 1.6;
+ font-family: var(--font-lato);
+ opacity: 0.85;
+}
+
+@media (max-width: 968px) {
+ .menuGrid {
+ grid-template-columns: 1fr;
+ }
+}
+
+@media (max-width: 768px) {
+ .heroTitle {
+ font-size: 3rem;
+ }
+
+ .menuSection {
+ padding: 40px 20px 60px;
+ }
+
+ .tabs {
+ gap: 1rem;
+ }
+
+ .tab {
+ padding: 10px 20px;
+ font-size: 0.9rem;
+ }
+
+ .menuCard {
+ flex-direction: column;
+ align-items: center;
+ text-align: center;
+ }
+
+ .imageFrame {
+ width: 150px;
+ height: 150px;
+ }
+
+ .cardHeader {
+ flex-direction: column;
+ gap: 0.5rem;
+ align-items: center;
+ }
+}
\ No newline at end of file
diff --git a/src/app/menu/page.tsx b/src/app/menu/page.tsx
new file mode 100644
index 0000000..f297a4b
--- /dev/null
+++ b/src/app/menu/page.tsx
@@ -0,0 +1,155 @@
+'use client'
+
+import { useState } from 'react';
+import Navbar from "@/components/Navbar/Navbar";
+import Footer from "@/components/Footer/Footer";
+import Image from "next/image";
+import Link from "next/link";
+import styles from "./menu.module.css";
+import { menuData } from "@/utils/constant";
+import { motion } from "framer-motion";
+
+export default function MenuPage() {
+ const [activeCategory, setActiveCategory] = useState(0);
+
+ // Animation variants
+ const heroVariants = {
+ hidden: { opacity: 0, y: -20 },
+ visible: {
+ opacity: 1,
+ y: 0,
+ transition: { duration: 0.8 }
+ }
+ };
+
+ const tabsVariants = {
+ hidden: { opacity: 0, y: 20 },
+ visible: {
+ opacity: 1,
+ y: 0,
+ transition: {
+ staggerChildren: 0.1,
+ delayChildren: 0.2
+ }
+ }
+ };
+
+ const tabVariants = {
+ hidden: { opacity: 0, y: 10 },
+ visible: {
+ opacity: 1,
+ y: 0,
+ transition: { duration: 0.4 }
+ }
+ };
+
+ const gridVariants = {
+ hidden: { opacity: 0 },
+ visible: {
+ opacity: 1,
+ transition: {
+ staggerChildren: 0.1,
+ delayChildren: 0.2
+ }
+ }
+ };
+
+ const cardVariants = {
+ hidden: { opacity: 0, y: 30 },
+ visible: {
+ opacity: 1,
+ y: 0,
+ transition: { duration: 0.5 }
+ }
+ };
+
+ return (
+
+
+
+
+
+
Our Menu
+
+ Home / Menu
+
+
+
+
+
+ {/* Category Tabs */}
+
+ {menuData.map((section, index) => (
+ setActiveCategory(index)}
+ variants={tabVariants}
+ whileHover={{ scale: 1.05 }}
+ whileTap={{ scale: 0.95 }}
+ >
+ {section.category}
+
+ ))}
+
+
+ {/* Menu Items Grid */}
+
+ {menuData[activeCategory].items.map((item, itemIndex) => (
+
+
+
+
+
+
{item.name}
+ {item.price}
+
+
{item.description}
+
+
+ ))}
+
+
+
+
+
+ );
+}
diff --git a/src/app/page.tsx b/src/app/page.tsx
index f16f831..05406e0 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -1,4 +1,3 @@
-import Navbar from "@/components/Navbar/Navbar";
import Hero from "@/components/Hero/Hero";
import PopularDishes from "@/components/PopularDishes/PopularDishes";
import About from "@/components/About/About";
@@ -11,7 +10,6 @@ import Footer from "@/components/Footer/Footer";
export default function Home() {
return (
-
diff --git a/src/components/About/About.tsx b/src/components/About/About.tsx
index 028c7d9..a13b4a2 100644
--- a/src/components/About/About.tsx
+++ b/src/components/About/About.tsx
@@ -1,20 +1,41 @@
+'use client'
+
import Image from 'next/image'
import Link from 'next/link'
import styles from './About.module.css'
+import { motion } from 'framer-motion'
export default function About() {
return (
-
-
+
+
-
-
+
+
{/* Decorative Icon SVG */}
@@ -31,8 +52,8 @@ export default function About() {
Learn More
-
-
+
+
)
}
diff --git a/src/components/Blogs/Blogs.module.css b/src/components/Blogs/Blogs.module.css
index 5662e34..3552525 100644
--- a/src/components/Blogs/Blogs.module.css
+++ b/src/components/Blogs/Blogs.module.css
@@ -1,9 +1,9 @@
.section {
padding: 80px 20px;
background-color: #3a0c08;
- /* Dark red/brown background */
- background-image: url('/images/pattern-overlay.png');
- /* Optional pattern */
+ background-image: url('/images/section-bg.jpg');
+ background-size: cover;
+ background-position: center;
text-align: center;
position: relative;
overflow: hidden;
@@ -21,19 +21,12 @@
.sliderContainer {
display: flex;
justify-content: center;
- align-items: center;
- gap: 20px;
- max-width: 1400px;
- margin: 0 auto;
- position: relative;
- padding: 0 40px;
-}
-
-.grid {
- display: grid;
- grid-template-columns: repeat(3, 1fr);
gap: 30px;
+ max-width: 1400px;
width: 100%;
+ position: relative;
+ padding: 0 60px;
+ margin: 0 auto;
}
.card {
@@ -46,7 +39,9 @@
flex-direction: column;
align-items: center;
transition: transform 0.3s ease;
- height: 100%;
+ flex: 0 0 calc(33.333% - 30px);
+ max-width: calc(33.333% - 30px);
+ box-sizing: border-box;
}
.card:hover {
@@ -103,20 +98,28 @@
}
.arrow {
- background: none;
- border: none;
+ position: absolute;
+ top: 50%;
+ transform: translateY(-50%);
color: #C5A059;
font-size: 3rem;
cursor: pointer;
+ background: none;
+ border: none;
transition: transform 0.2s;
- padding: 0 10px;
- display: flex;
- align-items: center;
- justify-content: center;
+ z-index: 10;
}
.arrow:hover {
- transform: scale(1.1);
+ transform: translateY(-50%) scale(1.1);
+}
+
+.prevArrow {
+ left: 0;
+}
+
+.nextArrow {
+ right: 0;
}
.viewMoreContainer {
@@ -127,15 +130,13 @@
display: inline-block;
padding: 15px 40px;
border: 1px solid #C5A059;
- color: #C5A059;
+ color: #fff;
font-family: var(--font-inter), sans-serif;
text-transform: uppercase;
font-size: 1rem;
text-decoration: none;
transition: all 0.3s ease;
background: transparent;
- border-radius: 5px;
- /* Slight radius as per some designs, or keep square */
border-radius: 8px;
}
@@ -144,12 +145,88 @@
color: #000;
}
-@media (max-width: 1024px) {
- .grid {
- grid-template-columns: 1fr;
+/* Responsive adjustments for different viewport sizes */
+@media (max-width: 1400px) {
+ .sliderContainer {
+ padding: 0 50px;
}
.arrow {
+ font-size: 2.8rem;
+ }
+}
+
+@media (max-width: 1200px) {
+ .sliderContainer {
+ padding: 0 40px;
+ }
+
+ .arrow {
+ font-size: 2.5rem;
+ }
+}
+
+@media (max-width: 1024px) {
+ .sliderContainer {
+ padding: 0 30px;
+ }
+
+ .card {
+ flex: 0 0 100%;
+ max-width: 100%;
+ }
+
+ /* Hide 2nd and 3rd cards on mobile, show only 1st */
+ .card:nth-child(2),
+ .card:nth-child(3) {
display: none;
}
+
+ .arrow {
+ font-size: 2.2rem;
+ }
+
+ .prevArrow {
+ left: 5px;
+ }
+
+ .nextArrow {
+ right: 5px;
+ }
+
+ .title {
+ font-size: 2.5rem;
+ }
+}
+
+@media (max-width: 768px) {
+ .sliderContainer {
+ padding: 0 20px;
+ }
+
+ .arrow {
+ font-size: 2rem;
+ }
+
+ .prevArrow {
+ left: 0;
+ }
+
+ .nextArrow {
+ right: 0;
+ }
+}
+
+@media (max-width: 480px) {
+ .sliderContainer {
+ padding: 0 15px;
+ }
+
+ .arrow {
+ font-size: 1.8rem;
+ }
+
+ .title {
+ font-size: 2rem;
+ }
}
\ No newline at end of file
diff --git a/src/components/Blogs/Blogs.tsx b/src/components/Blogs/Blogs.tsx
index 51ef48c..d7e6bcd 100644
--- a/src/components/Blogs/Blogs.tsx
+++ b/src/components/Blogs/Blogs.tsx
@@ -1,61 +1,73 @@
+'use client'
+
+import { useState, useEffect } from 'react'
import Image from 'next/image'
import Link from 'next/link'
import styles from './Blogs.module.css'
-
-const blogs = [
- {
- id: 1,
- title: 'The Art of Turkish Tea',
- image: '/images/dish-1.png', // Placeholder
- excerpt: 'Lorem ipsum dolor sit amet, tuem cergat imlpecion diirm, iadioc-ticid est nt eedrama inapat.'
- },
- {
- id: 2,
- title: 'Secrets of Charcoal Grilling',
- image: '/images/hero-3.png', // Placeholder
- excerpt: 'Lorem ipsum dolor sit amet, tuem cergat imlpecion diirm, iadioc-ticid est nt eedrama inapat.'
- },
- {
- id: 3,
- title: 'A Taste of Sweet Legacy',
- image: '/images/dish-2.png', // Placeholder
- excerpt: 'Lorem ipsum dolor sit amet, tuem cergat imlpecion diirm, iadioc-ticid est nt eedrama inapat.'
- }
-]
+import { blogData } from '@/utils/constant'
export default function Blogs() {
+ const [currentIndex, setCurrentIndex] = useState(0)
+
+ const nextSlide = () => {
+ setCurrentIndex((prev) => (prev + 1) % blogData.length)
+ }
+
+ const prevSlide = () => {
+ setCurrentIndex((prev) => (prev === 0 ? blogData.length - 1 : prev - 1))
+ }
+
+ // Auto-slide effect
+ useEffect(() => {
+ const interval = setInterval(() => {
+ setCurrentIndex((prev) => (prev + 1) % blogData.length)
+ }, 5000) // Change slide every 5 seconds
+
+ return () => clearInterval(interval)
+ }, [currentIndex])
+
+ // Get the 3 visible blogs
+ const getVisibleBlogs = () => {
+ const items = []
+ for (let i = 0; i < 3; i++) {
+ const index = (currentIndex + i) % blogData.length
+ items.push(blogData[index])
+ }
+ return items
+ }
+
+ const visibleItems = getVisibleBlogs()
+
return (
OUR BLOGS
-
←
+
←
-
- {blogs.map((blog) => (
-
-
-
-
-
{blog.title}
-
{blog.excerpt}
-
- View More
-
+ {visibleItems.map((blog) => (
+
+
{blog.title}
+
{blog.para}
+
+ View More
+
+
+ ))}
-
→
+
→
-
+
Read More Blogs
diff --git a/src/components/BookTable/BookTable.module.css b/src/components/BookTable/BookTable.module.css
index 8da3484..77f2c43 100644
--- a/src/components/BookTable/BookTable.module.css
+++ b/src/components/BookTable/BookTable.module.css
@@ -62,16 +62,14 @@
.inputGroup {
display: flex;
- align-items: center;
- gap: 1rem;
+ flex-direction: column;
+ gap: 0.5rem;
}
.label {
font-family: var(--font-playfair);
color: var(--color-gold);
- width: 80px;
font-size: 1.1rem;
- text-align: right;
}
.input,
@@ -83,7 +81,7 @@
padding: 0.8rem 1rem;
font-family: var(--font-lato);
font-size: 1rem;
- color: #333;
+ color: #757575;
outline: none;
transition: box-shadow 0.3s ease;
}
@@ -107,7 +105,7 @@
font-size: 1rem;
cursor: pointer;
transition: all 0.3s ease;
- align-self: flex-end;
+ align-self: center;
margin-top: 1rem;
border-radius: 4px;
}
@@ -124,6 +122,55 @@
font-family: var(--font-lato);
}
+/* Alert styles */
+.alert {
+ padding: 1rem;
+ margin-bottom: 1.5rem;
+ border-radius: 4px;
+ font-family: var(--font-lato);
+ text-align: center;
+}
+
+.alertSuccess {
+ background-color: rgba(40, 167, 69, 0.2);
+ color: #28a745;
+ border: 1px solid #28a745;
+}
+
+.alertDanger {
+ background-color: rgba(220, 53, 69, 0.2);
+ color: #dc3545;
+ border: 1px solid #dc3545;
+}
+
+/* Error text */
+.errorText {
+ color: #dc3545;
+ font-size: 0.875rem;
+ margin-top: 0.25rem;
+ display: block;
+ font-family: var(--font-lato);
+}
+
+/* Character count */
+.charCount {
+ color: var(--color-gold);
+ font-size: 0.875rem;
+ margin-top: 0.25rem;
+ display: block;
+ text-align: right;
+ font-family: var(--font-lato);
+}
+
+/* ReCAPTCHA wrapper */
+.recaptchaWrapper {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 0.5rem;
+ margin: 1rem 0;
+}
+
@media (min-width: 768px) {
.imageContainer {
display: block;
diff --git a/src/components/BookTable/BookTable.tsx b/src/components/BookTable/BookTable.tsx
index b25b4fa..9ecce6a 100644
--- a/src/components/BookTable/BookTable.tsx
+++ b/src/components/BookTable/BookTable.tsx
@@ -1,32 +1,121 @@
'use client'
-import { useState } from 'react'
+import { useState, useEffect } from 'react'
import Image from 'next/image'
+import ReCAPTCHA from "react-google-recaptcha"
+import axios from "axios"
import styles from './BookTable.module.css'
-import { submitReservation } from '@/app/actions'
+
+interface FormErrors {
+ name?: string;
+ phone?: string;
+ date?: string;
+ captcha?: string;
+}
export default function BookTable() {
- const [isSubmitting, setIsSubmitting] = useState(false)
- const [message, setMessage] = useState('')
+ const [email, setEmail] = useState("");
- async function handleSubmit(formData: FormData) {
- setIsSubmitting(true)
- setMessage('')
+ useEffect(() => {
+ const user = "info";
+ const domain = "antalya-restaurant.com";
+ setEmail(`${user}@${domain}`);
+ }, []);
+
+ const [formData, setFormData] = useState({
+ name: "",
+ phone: "",
+ date: "",
+ message: "",
+ });
+
+ const [formErrors, setFormErrors] = useState
({});
+ const [captchaToken, setCaptchaToken] = useState(null);
+ const [alert, setAlert] = useState({ show: false, type: "", message: "" });
+ const [charCount, setCharCount] = useState(0);
+
+ const handleChange = (e: React.ChangeEvent) => {
+ const { name, value } = e.target;
+ setFormData((prev) => ({ ...prev, [name]: value }));
+
+ if (name === "message") {
+ setCharCount(value.length);
+ }
+ };
+
+ const handleCaptchaChange = (token: string | null) => {
+ setCaptchaToken(token);
+ };
+
+ const handleSubmit = async (e: React.FormEvent) => {
+ e.preventDefault();
+
+ const errors: FormErrors = {};
+ if (!formData.name.trim()) errors.name = "Name is required.";
+ if (!formData.phone.trim()) errors.phone = "Phone is required.";
+ if (!formData.date.trim()) errors.date = "Date is required.";
+ if (!captchaToken) errors.captcha = "Please verify the CAPTCHA.";
+
+ setFormErrors(errors);
+ if (Object.keys(errors).length > 0) return;
+
+ const emailData = {
+ name: formData.name,
+ phone: formData.phone,
+ email: email,
+ subject: `Table Reservation - ${formData.name} on ${formData.date}`,
+ message: `
+ Reservation Details:
+ Name: ${formData.name}
+ Phone: ${formData.phone}
+ Date: ${formData.date}
+ Message:
+ ${formData.message || "None"}
+ `,
+ to: email,
+ senderName: "Antalya Restaurant - Table Reservation",
+ recaptchaToken: captchaToken,
+ };
try {
- const result = await submitReservation(formData)
- if (result.success) {
- setMessage(result.message)
- const form = document.getElementById('reservation-form') as HTMLFormElement
- form?.reset()
- }
+ const res = await axios.post(
+ "https://mailserver.metatronnest.com/send",
+ emailData,
+ { headers: { "Content-Type": "application/json" } }
+ );
+
+ setAlert({
+ show: true,
+ type: "success",
+ message: res?.data?.message || "Reservation request sent successfully! We'll contact you soon.",
+ });
+
+ setFormData({
+ name: "",
+ phone: "",
+ date: "",
+ message: "",
+ });
+ setCaptchaToken(null);
+ setFormErrors({});
+ setCharCount(0);
} catch (error) {
- console.error('Error submitting form:', error)
- setMessage('Something went wrong. Please try again.')
- } finally {
- setIsSubmitting(false)
+ setAlert({
+ show: true,
+ type: "danger",
+ message: "Failed to send reservation request. Please try again later.",
+ });
}
- }
+ };
+
+ useEffect(() => {
+ if (alert.show) {
+ const timer = setTimeout(() => {
+ setAlert((prev) => ({ ...prev, show: false }));
+ }, 5000);
+ return () => clearTimeout(timer);
+ }
+ }, [alert.show]);
return (
@@ -44,65 +133,96 @@ export default function BookTable() {
Book A Table
+ {alert.show && (
+
+ {alert.message}
+
+ )}
+
+ {/* Name Input with Placeholder */}
- Name
+ Name *
+ {formErrors.name && {formErrors.name} }
+ {/* Phone Input with Placeholder */}
- Phone
+ Phone *
+ {formErrors.phone && {formErrors.phone} }
- Date
+ Date *
+ {formErrors.date && {formErrors.date} }
+ {/* Message Textarea with Placeholder */}
Message
+ {charCount}/500 characters
-
-
- {isSubmitting ? 'Submitting...' : 'Submit Reservation'}
+ Submit Reservation
- {message && {message}
}
+
+
+ {formErrors.captcha && {formErrors.captcha} }
+
+
+
)
-}
+}
\ No newline at end of file
diff --git a/src/components/FAQ/FAQ.module.css b/src/components/FAQ/FAQ.module.css
new file mode 100644
index 0000000..73fb2ae
--- /dev/null
+++ b/src/components/FAQ/FAQ.module.css
@@ -0,0 +1,123 @@
+.faqSection {
+ padding: 30px 20px 60px 20px;
+ /* background-color: #F5E6D3; */
+ max-width: 1200px;
+ margin: 0 auto;
+}
+
+.faqTitle {
+ font-family: var(--font-playfair);
+ font-size: 2.5rem;
+ color: #5d4037;
+ text-align: start;
+ margin-bottom: 3rem;
+ text-transform: uppercase;
+ letter-spacing: 2px;
+}
+
+.faqContainer {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+}
+
+.faqItem {
+ background: #fff;
+ border: 2px solid #C5A059;
+ border-radius: 8px;
+ overflow: hidden;
+ transition: all 0.3s ease;
+}
+
+.faqItem:hover {
+ box-shadow: 0 4px 12px rgba(197, 160, 89, 0.2);
+}
+
+.faqQuestion {
+ width: 100%;
+ padding: 1.5rem 2rem;
+ background: transparent;
+ border: none;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ cursor: pointer;
+ font-family: var(--font-lato);
+ font-size: 1.1rem;
+ font-weight: 600;
+ color: #5d4037;
+ text-align: left;
+ transition: all 0.3s ease;
+}
+
+.faqQuestion:hover {
+ background-color: #faf6f0;
+}
+
+.faqQuestion.active {
+ background-color: #C5A059;
+ color: #fff;
+}
+
+.icon {
+ font-size: 1.5rem;
+ font-weight: bold;
+ color: #C5A059;
+ transition: transform 0.3s ease;
+ flex-shrink: 0;
+ margin-left: 1rem;
+}
+
+.faqQuestion.active .icon {
+ color: #fff;
+ transform: rotate(180deg);
+}
+
+.faqAnswer {
+ max-height: 0;
+ overflow: hidden;
+ transition: max-height 0.4s ease, padding 0.4s ease;
+}
+
+.faqAnswer.open {
+ max-height: 1000px;
+ padding: 1.5rem 2rem;
+ border-top: 1px solid #e0d5c7;
+}
+
+.faqContent {
+ font-family: var(--font-lato);
+ font-size: 1rem;
+ color: #5d4037;
+ line-height: 1.8;
+}
+
+.faqContent a {
+ color: #C5A059;
+ text-decoration: underline;
+ transition: color 0.3s;
+}
+
+.faqContent a:hover {
+ color: #b08f4a;
+}
+
+@media (max-width: 768px) {
+ .faqSection {
+ padding: 40px 15px;
+ }
+
+ .faqTitle {
+ font-size: 2rem;
+ margin-bottom: 2rem;
+ }
+
+ .faqQuestion {
+ padding: 1.2rem 1.5rem;
+ font-size: 1rem;
+ }
+
+ .faqAnswer.open {
+ padding: 1.2rem 1.5rem;
+ }
+}
\ No newline at end of file
diff --git a/src/components/FAQ/FAQ.tsx b/src/components/FAQ/FAQ.tsx
new file mode 100644
index 0000000..39233d1
--- /dev/null
+++ b/src/components/FAQ/FAQ.tsx
@@ -0,0 +1,46 @@
+'use client'
+
+import { useState } from 'react';
+import styles from './FAQ.module.css';
+
+interface FAQItem {
+ q: string;
+ a: string;
+}
+
+interface FAQProps {
+ faqs: FAQItem[];
+}
+
+export default function FAQ({ faqs }: FAQProps) {
+ const [openIndex, setOpenIndex] = useState(null);
+
+ const toggleFAQ = (index: number) => {
+ setOpenIndex(openIndex === index ? null : index);
+ };
+
+ return (
+
+
FAQs
+
+ {faqs.map((faq, index) => (
+
+
toggleFAQ(index)}
+ >
+ {faq.q}
+ {openIndex === index ? '−' : '+'}
+
+
+
+ ))}
+
+
+ );
+}
diff --git a/src/components/Footer.tsx b/src/components/Footer.tsx
new file mode 100644
index 0000000..63091b9
--- /dev/null
+++ b/src/components/Footer.tsx
@@ -0,0 +1,16 @@
+import React from 'react';
+import styles from '@/app/about/about.module.css'; // reuse styles or define minimal inline
+
+export default function Footer() {
+ return (
+
+ );
+}
diff --git a/src/components/Footer/Footer.module.css b/src/components/Footer/Footer.module.css
index 7538841..2de7b9e 100644
--- a/src/components/Footer/Footer.module.css
+++ b/src/components/Footer/Footer.module.css
@@ -1,5 +1,6 @@
.footer {
background-color: #2a0a0a;
+ background-image: url('/images/section-bg.jpg');
/* Deep red/brown */
color: #d4b060;
/* Gold-ish text */
@@ -7,6 +8,21 @@
border-top: 1px solid var(--color-gold);
}
+/* Add this (or adjust as needed) to Footer.module.css */
+
+.logoImage {
+ /* Style the Next.js Image component inside the logo container */
+ width: auto;
+ height: 100px;
+ /* Example height - adjust this to your desired size */
+ max-width: 100%;
+}
+
+.logoa {
+ /* Ensure the link container doesn't disrupt layout */
+ display: inline-block;
+}
+
.container {
max-width: 1200px;
margin: 0 auto;
@@ -57,7 +73,7 @@
display: flex;
align-items: center;
justify-content: center;
- color: #2a0a0a;
+ color: #ffff;
font-weight: bold;
}
diff --git a/src/components/Footer/Footer.tsx b/src/components/Footer/Footer.tsx
index 5d0007f..54a0a33 100644
--- a/src/components/Footer/Footer.tsx
+++ b/src/components/Footer/Footer.tsx
@@ -1,15 +1,32 @@
+'use client'
+
+import Image from 'next/image'
+import Link from 'next/link'
import styles from './Footer.module.css'
export default function Footer() {
+
+ const metatronCubeLink = "https://metatroncubesolutions.com/";
+
return (