diff --git a/messages/de.json b/messages/de.json
index b5ac31c..5ca66b1 100644
--- a/messages/de.json
+++ b/messages/de.json
@@ -2,15 +2,31 @@
"Header": {
"registration": "Registration",
"enter": "Enter",
+ "account": "My Account",
"menu": {
- "faq": "Start grow with BB",
- "experts": "Become BB Expert",
- "news": "Blog&News"
+ "bb-client": "Start grow with BB",
+ "bb-expert": "Become BB Expert",
+ "blog": "Blog&News"
}
},
"Main": {
"title": "Bbuddy - Main",
- "description": "Bbuddy desc"
+ "description": "Bbuddy desc",
+ "header": "Mentorship, Career\nDevelopment & Coaching.",
+ "header-desc": "The ins-and-outs of building a career in tech, gaining experience from a mentor, and getting your feet wet with coaching.",
+ "news": "Professional Articles & Project News",
+ "popular": "Popular Topics"
+ },
+ "BbClient": {
+ "title": "Bbuddy - Client",
+ "description": "Bbuddy desc client",
+ "header": "Personal, professional, and business\ndevelopment mobile application"
+ },
+ "BbExpert": {
+ "title": "Bbuddy - Expert",
+ "description": "Bbuddy desc expert",
+ "header": "Be where your customers are",
+ "header-desc": "B Buddy is an application for active people interested in growth on all fronts — personal, professional and business. Right now they are looking for you."
},
"Account": {
"menu": {
@@ -71,5 +87,22 @@
"faq": "FAQ",
"privacy-policy": "Privacy Policy"
}
+ },
+ "Experts": {
+ "title": "Find a expert",
+ "filter": {
+ "price": "Price from {from}€ to {to}€",
+ "duration": "Duration from {from}min to {to}min",
+ "apply": "Apply",
+ "find": "Find",
+ "search": "Search for an Expert",
+ "sort": "Sort",
+ "language": "Language"
+ },
+ "list": {
+ "price": "0€",
+ "duration": "0min",
+ "details": "Details"
+ }
}
}
diff --git a/messages/en.json b/messages/en.json
index a007dde..5ca66b1 100644
--- a/messages/en.json
+++ b/messages/en.json
@@ -2,16 +2,31 @@
"Header": {
"registration": "Registration",
"enter": "Enter",
+ "account": "My Account",
"menu": {
- "faq": "Start grow with BB",
- "experts": "Become BB Expert",
- "news": "Blog&News"
+ "bb-client": "Start grow with BB",
+ "bb-expert": "Become BB Expert",
+ "blog": "Blog&News"
}
},
"Main": {
"title": "Bbuddy - Main",
"description": "Bbuddy desc",
- "news": "Professional Articles & Project News"
+ "header": "Mentorship, Career\nDevelopment & Coaching.",
+ "header-desc": "The ins-and-outs of building a career in tech, gaining experience from a mentor, and getting your feet wet with coaching.",
+ "news": "Professional Articles & Project News",
+ "popular": "Popular Topics"
+ },
+ "BbClient": {
+ "title": "Bbuddy - Client",
+ "description": "Bbuddy desc client",
+ "header": "Personal, professional, and business\ndevelopment mobile application"
+ },
+ "BbExpert": {
+ "title": "Bbuddy - Expert",
+ "description": "Bbuddy desc expert",
+ "header": "Be where your customers are",
+ "header-desc": "B Buddy is an application for active people interested in growth on all fronts — personal, professional and business. Right now they are looking for you."
},
"Account": {
"menu": {
@@ -72,5 +87,22 @@
"faq": "FAQ",
"privacy-policy": "Privacy Policy"
}
+ },
+ "Experts": {
+ "title": "Find a expert",
+ "filter": {
+ "price": "Price from {from}€ to {to}€",
+ "duration": "Duration from {from}min to {to}min",
+ "apply": "Apply",
+ "find": "Find",
+ "search": "Search for an Expert",
+ "sort": "Sort",
+ "language": "Language"
+ },
+ "list": {
+ "price": "0€",
+ "duration": "0min",
+ "details": "Details"
+ }
}
}
diff --git a/messages/es.json b/messages/es.json
index b5ac31c..5ca66b1 100644
--- a/messages/es.json
+++ b/messages/es.json
@@ -2,15 +2,31 @@
"Header": {
"registration": "Registration",
"enter": "Enter",
+ "account": "My Account",
"menu": {
- "faq": "Start grow with BB",
- "experts": "Become BB Expert",
- "news": "Blog&News"
+ "bb-client": "Start grow with BB",
+ "bb-expert": "Become BB Expert",
+ "blog": "Blog&News"
}
},
"Main": {
"title": "Bbuddy - Main",
- "description": "Bbuddy desc"
+ "description": "Bbuddy desc",
+ "header": "Mentorship, Career\nDevelopment & Coaching.",
+ "header-desc": "The ins-and-outs of building a career in tech, gaining experience from a mentor, and getting your feet wet with coaching.",
+ "news": "Professional Articles & Project News",
+ "popular": "Popular Topics"
+ },
+ "BbClient": {
+ "title": "Bbuddy - Client",
+ "description": "Bbuddy desc client",
+ "header": "Personal, professional, and business\ndevelopment mobile application"
+ },
+ "BbExpert": {
+ "title": "Bbuddy - Expert",
+ "description": "Bbuddy desc expert",
+ "header": "Be where your customers are",
+ "header-desc": "B Buddy is an application for active people interested in growth on all fronts — personal, professional and business. Right now they are looking for you."
},
"Account": {
"menu": {
@@ -71,5 +87,22 @@
"faq": "FAQ",
"privacy-policy": "Privacy Policy"
}
+ },
+ "Experts": {
+ "title": "Find a expert",
+ "filter": {
+ "price": "Price from {from}€ to {to}€",
+ "duration": "Duration from {from}min to {to}min",
+ "apply": "Apply",
+ "find": "Find",
+ "search": "Search for an Expert",
+ "sort": "Sort",
+ "language": "Language"
+ },
+ "list": {
+ "price": "0€",
+ "duration": "0min",
+ "details": "Details"
+ }
}
}
diff --git a/messages/fr.json b/messages/fr.json
index b5ac31c..5ca66b1 100644
--- a/messages/fr.json
+++ b/messages/fr.json
@@ -2,15 +2,31 @@
"Header": {
"registration": "Registration",
"enter": "Enter",
+ "account": "My Account",
"menu": {
- "faq": "Start grow with BB",
- "experts": "Become BB Expert",
- "news": "Blog&News"
+ "bb-client": "Start grow with BB",
+ "bb-expert": "Become BB Expert",
+ "blog": "Blog&News"
}
},
"Main": {
"title": "Bbuddy - Main",
- "description": "Bbuddy desc"
+ "description": "Bbuddy desc",
+ "header": "Mentorship, Career\nDevelopment & Coaching.",
+ "header-desc": "The ins-and-outs of building a career in tech, gaining experience from a mentor, and getting your feet wet with coaching.",
+ "news": "Professional Articles & Project News",
+ "popular": "Popular Topics"
+ },
+ "BbClient": {
+ "title": "Bbuddy - Client",
+ "description": "Bbuddy desc client",
+ "header": "Personal, professional, and business\ndevelopment mobile application"
+ },
+ "BbExpert": {
+ "title": "Bbuddy - Expert",
+ "description": "Bbuddy desc expert",
+ "header": "Be where your customers are",
+ "header-desc": "B Buddy is an application for active people interested in growth on all fronts — personal, professional and business. Right now they are looking for you."
},
"Account": {
"menu": {
@@ -71,5 +87,22 @@
"faq": "FAQ",
"privacy-policy": "Privacy Policy"
}
+ },
+ "Experts": {
+ "title": "Find a expert",
+ "filter": {
+ "price": "Price from {from}€ to {to}€",
+ "duration": "Duration from {from}min to {to}min",
+ "apply": "Apply",
+ "find": "Find",
+ "search": "Search for an Expert",
+ "sort": "Sort",
+ "language": "Language"
+ },
+ "list": {
+ "price": "0€",
+ "duration": "0min",
+ "details": "Details"
+ }
}
}
diff --git a/messages/it.json b/messages/it.json
index b5ac31c..5ca66b1 100644
--- a/messages/it.json
+++ b/messages/it.json
@@ -2,15 +2,31 @@
"Header": {
"registration": "Registration",
"enter": "Enter",
+ "account": "My Account",
"menu": {
- "faq": "Start grow with BB",
- "experts": "Become BB Expert",
- "news": "Blog&News"
+ "bb-client": "Start grow with BB",
+ "bb-expert": "Become BB Expert",
+ "blog": "Blog&News"
}
},
"Main": {
"title": "Bbuddy - Main",
- "description": "Bbuddy desc"
+ "description": "Bbuddy desc",
+ "header": "Mentorship, Career\nDevelopment & Coaching.",
+ "header-desc": "The ins-and-outs of building a career in tech, gaining experience from a mentor, and getting your feet wet with coaching.",
+ "news": "Professional Articles & Project News",
+ "popular": "Popular Topics"
+ },
+ "BbClient": {
+ "title": "Bbuddy - Client",
+ "description": "Bbuddy desc client",
+ "header": "Personal, professional, and business\ndevelopment mobile application"
+ },
+ "BbExpert": {
+ "title": "Bbuddy - Expert",
+ "description": "Bbuddy desc expert",
+ "header": "Be where your customers are",
+ "header-desc": "B Buddy is an application for active people interested in growth on all fronts — personal, professional and business. Right now they are looking for you."
},
"Account": {
"menu": {
@@ -71,5 +87,22 @@
"faq": "FAQ",
"privacy-policy": "Privacy Policy"
}
+ },
+ "Experts": {
+ "title": "Find a expert",
+ "filter": {
+ "price": "Price from {from}€ to {to}€",
+ "duration": "Duration from {from}min to {to}min",
+ "apply": "Apply",
+ "find": "Find",
+ "search": "Search for an Expert",
+ "sort": "Sort",
+ "language": "Language"
+ },
+ "list": {
+ "price": "0€",
+ "duration": "0min",
+ "details": "Details"
+ }
}
}
diff --git a/messages/ru.json b/messages/ru.json
index b3bca11..64fb88a 100644
--- a/messages/ru.json
+++ b/messages/ru.json
@@ -2,15 +2,31 @@
"Header": {
"registration": "Регистрация",
"enter": "Вход",
+ "account": "Мой аккаунт",
"menu": {
- "faq": "Начни вместе с BB",
- "experts": "Стань BB экспертом",
- "news": "Блог&Новости"
+ "bb-client": "Начни вместе с BB",
+ "bb-expert": "Стань BB экспертом",
+ "blog": "Блог&Новости"
}
},
"Main": {
"title": "Bbuddy - Главная",
- "description": "Bbuddy описание"
+ "description": "Bbuddy описание",
+ "header": "Mentorship, Career\nDevelopment & Coaching.",
+ "header-desc": "The ins-and-outs of building a career in tech, gaining experience from a mentor, and getting your feet wet with coaching.",
+ "news": "Professional Articles & Project News",
+ "popular": "Popular Topics"
+ },
+ "BbClient": {
+ "title": "Bbuddy - Client",
+ "description": "Bbuddy desc client",
+ "header": "Personal, professional, and business\ndevelopment mobile application"
+ },
+ "BbExpert": {
+ "title": "Bbuddy - Expert",
+ "description": "Bbuddy desc expert",
+ "header": "Be where your customers are",
+ "header-desc": "B Buddy is an application for active people interested in growth on all fronts — personal, professional and business. Right now they are looking for you."
},
"Account": {
"menu": {
@@ -71,5 +87,22 @@
"faq": "Помощь",
"privacy-policy": "Политика конфиденциальности"
}
+ },
+ "Experts": {
+ "title": "Найти эксперта",
+ "filter": {
+ "price": "Цена от {from}₽ до {to}₽",
+ "duration": "Продолжительность от {from}мин до {to}мин",
+ "apply": "Применить",
+ "find": "Найти",
+ "search": "Поиск",
+ "sort": "Сортировка",
+ "language": "Язык"
+ },
+ "list": {
+ "price": "0₽",
+ "duration": "0мин",
+ "details": "Детали"
+ }
}
}
diff --git a/next.config.js b/next.config.js
index 9ff142f..d0522af 100644
--- a/next.config.js
+++ b/next.config.js
@@ -19,22 +19,13 @@ const nextConfig = {
},
experimental: {
taint: true,
- typedRoutes: true
+ // typedRoutes: true
},
output: 'export',
distDir: 'dist',
poweredByHeader: false,
productionBrowserSourceMaps: true,
trailingSlash: true
- // redirects: async () => {
- // return [
- // {
- // source: '/en/',
- // destination: '/en.html',
- // permanent: true
- // }
- // ]
- // }
};
module.exports = withNextIntl(nextConfig);
diff --git a/package-lock.json b/package-lock.json
index 238a69c..bba5b5d 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -16,6 +16,8 @@
"next-intl": "^3.3.1",
"react": "^18",
"react-dom": "^18",
+ "react-slick": "^0.29.0",
+ "slick-carousel": "^1.8.1",
"styled-components": "^6.1.1"
},
"devDependencies": {
@@ -1617,6 +1619,11 @@
"node": ">=10.13.0"
}
},
+ "node_modules/enquire.js": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/enquire.js/-/enquire.js-2.1.6.tgz",
+ "integrity": "sha512-/KujNpO+PT63F7Hlpu4h3pE3TokKRHN26JYmQpPyjkRD/N57R7bPDNojMXdi7uveAKjYB7yQnartCxZnFWr0Xw=="
+ },
"node_modules/es-abstract": {
"version": "1.22.3",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz",
@@ -3071,6 +3078,12 @@
"set-function-name": "^2.0.1"
}
},
+ "node_modules/jquery": {
+ "version": "3.7.1",
+ "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz",
+ "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==",
+ "peer": true
+ },
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -3196,6 +3209,11 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/lodash.debounce": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
+ "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="
+ },
"node_modules/lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
@@ -4356,6 +4374,22 @@
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
"dev": true
},
+ "node_modules/react-slick": {
+ "version": "0.29.0",
+ "resolved": "https://registry.npmjs.org/react-slick/-/react-slick-0.29.0.tgz",
+ "integrity": "sha512-TGdOKE+ZkJHHeC4aaoH85m8RnFyWqdqRfAGkhd6dirmATXMZWAxOpTLmw2Ll/jPTQ3eEG7ercFr/sbzdeYCJXA==",
+ "dependencies": {
+ "classnames": "^2.2.5",
+ "enquire.js": "^2.1.6",
+ "json2mq": "^0.2.0",
+ "lodash.debounce": "^4.0.8",
+ "resize-observer-polyfill": "^1.5.0"
+ },
+ "peerDependencies": {
+ "react": "^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0",
+ "react-dom": "^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
"node_modules/readdirp": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
@@ -4656,6 +4690,14 @@
"node": ">=8"
}
},
+ "node_modules/slick-carousel": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/slick-carousel/-/slick-carousel-1.8.1.tgz",
+ "integrity": "sha512-XB9Ftrf2EEKfzoQXt3Nitrt/IPbT+f1fgqBdoxO3W/+JYvtEOW6EgxnWfr9GH6nmULv7Y2tPmEX3koxThVmebA==",
+ "peerDependencies": {
+ "jquery": ">=1.8.0"
+ }
+ },
"node_modules/source-map-js": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
@@ -6376,6 +6418,11 @@
"tapable": "^2.2.0"
}
},
+ "enquire.js": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/enquire.js/-/enquire.js-2.1.6.tgz",
+ "integrity": "sha512-/KujNpO+PT63F7Hlpu4h3pE3TokKRHN26JYmQpPyjkRD/N57R7bPDNojMXdi7uveAKjYB7yQnartCxZnFWr0Xw=="
+ },
"es-abstract": {
"version": "1.22.3",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz",
@@ -7449,6 +7496,12 @@
"set-function-name": "^2.0.1"
}
},
+ "jquery": {
+ "version": "3.7.1",
+ "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz",
+ "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==",
+ "peer": true
+ },
"js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -7553,6 +7606,11 @@
"p-locate": "^5.0.0"
}
},
+ "lodash.debounce": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
+ "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="
+ },
"lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
@@ -8337,6 +8395,18 @@
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
"dev": true
},
+ "react-slick": {
+ "version": "0.29.0",
+ "resolved": "https://registry.npmjs.org/react-slick/-/react-slick-0.29.0.tgz",
+ "integrity": "sha512-TGdOKE+ZkJHHeC4aaoH85m8RnFyWqdqRfAGkhd6dirmATXMZWAxOpTLmw2Ll/jPTQ3eEG7ercFr/sbzdeYCJXA==",
+ "requires": {
+ "classnames": "^2.2.5",
+ "enquire.js": "^2.1.6",
+ "json2mq": "^0.2.0",
+ "lodash.debounce": "^4.0.8",
+ "resize-observer-polyfill": "^1.5.0"
+ }
+ },
"readdirp": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
@@ -8547,6 +8617,12 @@
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
"dev": true
},
+ "slick-carousel": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/slick-carousel/-/slick-carousel-1.8.1.tgz",
+ "integrity": "sha512-XB9Ftrf2EEKfzoQXt3Nitrt/IPbT+f1fgqBdoxO3W/+JYvtEOW6EgxnWfr9GH6nmULv7Y2tPmEX3koxThVmebA==",
+ "requires": {}
+ },
"source-map-js": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
diff --git a/package.json b/package.json
index df52fec..ac8b2e7 100644
--- a/package.json
+++ b/package.json
@@ -17,6 +17,8 @@
"next-intl": "^3.3.1",
"react": "^18",
"react-dom": "^18",
+ "react-slick": "^0.29.0",
+ "slick-carousel": "^1.8.1",
"styled-components": "^6.1.1"
},
"devDependencies": {
diff --git a/public/docs/BBUDDY_privacy_policy_fin.docx b/public/docs/BBUDDY_privacy_policy_fin.docx
new file mode 100644
index 0000000..7a12cdf
Binary files /dev/null and b/public/docs/BBUDDY_privacy_policy_fin.docx differ
diff --git a/public/images/b-2-bg.png b/public/images/b-2-bg.png
new file mode 100644
index 0000000..d2e143e
Binary files /dev/null and b/public/images/b-2-bg.png differ
diff --git a/public/images/b-3-1.svg b/public/images/b-3-1.svg
new file mode 100644
index 0000000..33b884f
--- /dev/null
+++ b/public/images/b-3-1.svg
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/images/b-3-2.svg b/public/images/b-3-2.svg
new file mode 100644
index 0000000..c29df5b
--- /dev/null
+++ b/public/images/b-3-2.svg
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/images/b-3-3.svg b/public/images/b-3-3.svg
new file mode 100644
index 0000000..8fb9eb9
--- /dev/null
+++ b/public/images/b-3-3.svg
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/images/b-3-4.svg b/public/images/b-3-4.svg
new file mode 100644
index 0000000..0f846da
--- /dev/null
+++ b/public/images/b-3-4.svg
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/images/b-5-1.svg b/public/images/b-5-1.svg
new file mode 100644
index 0000000..088e3c6
--- /dev/null
+++ b/public/images/b-5-1.svg
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/images/b-5-2.svg b/public/images/b-5-2.svg
new file mode 100644
index 0000000..a45491a
--- /dev/null
+++ b/public/images/b-5-2.svg
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/images/b-5-3.svg b/public/images/b-5-3.svg
new file mode 100644
index 0000000..6e5910a
--- /dev/null
+++ b/public/images/b-5-3.svg
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/images/b-5-4.svg b/public/images/b-5-4.svg
new file mode 100644
index 0000000..1375c93
--- /dev/null
+++ b/public/images/b-5-4.svg
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/images/b-6-img.png b/public/images/b-6-img.png
new file mode 100644
index 0000000..3b48002
Binary files /dev/null and b/public/images/b-6-img.png differ
diff --git a/public/images/banner-people.png b/public/images/banner-people.png
new file mode 100644
index 0000000..ff2127e
Binary files /dev/null and b/public/images/banner-people.png differ
diff --git a/public/images/banner-phone.png b/public/images/banner-phone.png
new file mode 100644
index 0000000..45d133b
Binary files /dev/null and b/public/images/banner-phone.png differ
diff --git a/public/images/calendar.svg b/public/images/calendar.svg
new file mode 100644
index 0000000..934c72a
--- /dev/null
+++ b/public/images/calendar.svg
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/images/call-outline-white.svg b/public/images/call-outline-white.svg
new file mode 100644
index 0000000..94e7469
--- /dev/null
+++ b/public/images/call-outline-white.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/public/images/cash.svg b/public/images/cash.svg
new file mode 100644
index 0000000..90a784b
--- /dev/null
+++ b/public/images/cash.svg
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/public/images/comission.svg b/public/images/comission.svg
new file mode 100644
index 0000000..9f43c55
--- /dev/null
+++ b/public/images/comission.svg
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/public/images/faq-img.png b/public/images/faq-img.png
new file mode 100644
index 0000000..a7121de
Binary files /dev/null and b/public/images/faq-img.png differ
diff --git a/public/images/feedback.svg b/public/images/feedback.svg
new file mode 100644
index 0000000..ad5bd55
--- /dev/null
+++ b/public/images/feedback.svg
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/public/images/girl.png b/public/images/girl.png
new file mode 100644
index 0000000..91662a4
Binary files /dev/null and b/public/images/girl.png differ
diff --git a/public/images/guard.svg b/public/images/guard.svg
new file mode 100644
index 0000000..bd63122
--- /dev/null
+++ b/public/images/guard.svg
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/images/man.svg b/public/images/man.svg
new file mode 100644
index 0000000..2266535
--- /dev/null
+++ b/public/images/man.svg
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/images/new-client.svg b/public/images/new-client.svg
new file mode 100644
index 0000000..2ab1fd1
--- /dev/null
+++ b/public/images/new-client.svg
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/public/images/new-expert.svg b/public/images/new-expert.svg
new file mode 100644
index 0000000..b2040e7
--- /dev/null
+++ b/public/images/new-expert.svg
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/public/images/note.svg b/public/images/note.svg
new file mode 100644
index 0000000..d0e5709
--- /dev/null
+++ b/public/images/note.svg
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/public/images/search.svg b/public/images/search.svg
new file mode 100644
index 0000000..e6135cd
--- /dev/null
+++ b/public/images/search.svg
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/public/images/slider-1.png b/public/images/slider-1.png
new file mode 100644
index 0000000..259bc8b
Binary files /dev/null and b/public/images/slider-1.png differ
diff --git a/public/images/slider-2.png b/public/images/slider-2.png
new file mode 100644
index 0000000..e21b6a6
Binary files /dev/null and b/public/images/slider-2.png differ
diff --git a/public/images/slider-3.png b/public/images/slider-3.png
new file mode 100644
index 0000000..3f603f2
Binary files /dev/null and b/public/images/slider-3.png differ
diff --git a/public/images/slider-4.png b/public/images/slider-4.png
new file mode 100644
index 0000000..e21b6a6
Binary files /dev/null and b/public/images/slider-4.png differ
diff --git a/public/images/slider-5.png b/public/images/slider-5.png
new file mode 100644
index 0000000..e21b6a6
Binary files /dev/null and b/public/images/slider-5.png differ
diff --git a/public/images/slider-nahd.png b/public/images/slider-nahd.png
new file mode 100644
index 0000000..ef214e3
Binary files /dev/null and b/public/images/slider-nahd.png differ
diff --git a/public/images/target.svg b/public/images/target.svg
new file mode 100644
index 0000000..79a40d5
--- /dev/null
+++ b/public/images/target.svg
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/images/videocall.svg b/public/images/videocall.svg
new file mode 100644
index 0000000..4a5c927
--- /dev/null
+++ b/public/images/videocall.svg
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/public/images/waves-top.png b/public/images/waves-top.png
new file mode 100644
index 0000000..0cbeb37
Binary files /dev/null and b/public/images/waves-top.png differ
diff --git a/public/images/white-ball.svg b/public/images/white-ball.svg
new file mode 100644
index 0000000..c9c8b52
--- /dev/null
+++ b/public/images/white-ball.svg
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/actions/tags.ts b/src/actions/tags.ts
new file mode 100644
index 0000000..e1726a3
--- /dev/null
+++ b/src/actions/tags.ts
@@ -0,0 +1,17 @@
+import { apiClient } from '../lib/apiClient';
+import { SearchData } from '../types/tags';
+
+export const getTagList = async (locale: string) => {
+ const response = await apiClient.post(
+ '/home/searchdata',
+ {},
+ {
+ headers: {
+ 'X-User-Language': locale,
+ Authorization: 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImN0eSI6IkpXVCJ9.eyJuYW1laWQiOiIxNzIiLCJuYmYiOjE3MDM2ODMyMDgsImV4cCI6MTczNTIxOTIwOCwiaWF0IjoxNzAzNjgzMjA4fQ.KgnYfKO7oVFLlDuKhfyNN6RAaXKdeSzJd7F4r6_15AA'
+ }
+ }
+ );
+
+ return response.data as SearchData || null;
+};
diff --git a/src/app/[locale]/(main)/@experts/page.tsx b/src/app/[locale]/(main)/@experts/page.tsx
index d17297d..8f6fd3c 100644
--- a/src/app/[locale]/(main)/@experts/page.tsx
+++ b/src/app/[locale]/(main)/@experts/page.tsx
@@ -1,40 +1,30 @@
import React from 'react';
-import { CustomPagination } from '../../../../components/view';
-import { ExpertsFilter } from '../../../../components/Experts/Filter';
-import { ExpertsAdditionalFilter } from '../../../../components/Experts/AdditionalFilter';
-import { ExpertsList } from '../../../../components/Experts/ExpertsList';
+import { getTranslations } from 'next-intl/server';
+import { getFilter } from '../../../../utils/filter';
import { getExpertsList } from '../../../../actions/experts';
+import { getTagList } from '../../../../actions/tags';
+import { Experts } from '../../../../components/Experts/Experts';
-export default async function Experts({ params }: { params: { locale: string } }) {
- const data = await getExpertsList({
- "themesTagIds": [
- 1,2,3,4,5,6,7,8
- ],
- "priceFrom": null,
- "priceTo": null,
- "durationFrom": null,
- "durationTo": null
- }, params.locale);
+export default async function ExpertsPage({ params, searchParams }: { params: { locale: string }, searchParams: { [key: string]: string | string[] | undefined } }) {
+ const searchData = await getTagList(params.locale);
+ const filter = getFilter(searchData, searchParams);
+ console.log('filter main page', filter);
+ const experts = await getExpertsList(filter, params.locale);
+ const t = await getTranslations('Experts');
return (
-
Find an expert
+
{t('title')}
-
+
);
diff --git a/src/app/[locale]/(main)/page.tsx b/src/app/[locale]/(main)/page.tsx
index 98b0131..63f0773 100644
--- a/src/app/[locale]/(main)/page.tsx
+++ b/src/app/[locale]/(main)/page.tsx
@@ -1,5 +1,7 @@
import React from 'react';
import type { Metadata } from 'next';
+import { useTranslations } from 'next-intl';
+import { GeneralTopSection } from '../../../components/Page';
export const metadata: Metadata = {
title: 'Bbuddy - Main',
@@ -7,41 +9,13 @@ export const metadata: Metadata = {
};
export default function Home() {
+ const t = useTranslations('Main');
+
return (
-
-
-
- Mentorship, Career
- Development & Coaching.
-
-
-
The ins-and-outs of building a career in tech, gaining experience
-
from a mentor, and getting your feet wet with coaching.
-
-
-
-
-
-
-
+
);
};
diff --git a/src/app/[locale]/[userId]/page.tsx b/src/app/[locale]/[userId]/page.tsx
deleted file mode 100644
index f34d062..0000000
--- a/src/app/[locale]/[userId]/page.tsx
+++ /dev/null
@@ -1,5 +0,0 @@
-import { redirect } from 'next/navigation';
-
-export default function AccountMainPage({ params }: { params: { userId: string } }) {
- redirect(`/${params.userId}/sessions`);
-};
diff --git a/src/app/[locale]/[userId]/information/page.tsx b/src/app/[locale]/account/information/page.tsx
similarity index 100%
rename from src/app/[locale]/[userId]/information/page.tsx
rename to src/app/[locale]/account/information/page.tsx
diff --git a/src/app/[locale]/[userId]/layout.tsx b/src/app/[locale]/account/layout.tsx
similarity index 100%
rename from src/app/[locale]/[userId]/layout.tsx
rename to src/app/[locale]/account/layout.tsx
diff --git a/src/app/[locale]/[userId]/messages/[textId]/page.tsx b/src/app/[locale]/account/messages/[textId]/page.tsx
similarity index 100%
rename from src/app/[locale]/[userId]/messages/[textId]/page.tsx
rename to src/app/[locale]/account/messages/[textId]/page.tsx
diff --git a/src/app/[locale]/[userId]/messages/page.tsx b/src/app/[locale]/account/messages/page.tsx
similarity index 100%
rename from src/app/[locale]/[userId]/messages/page.tsx
rename to src/app/[locale]/account/messages/page.tsx
diff --git a/src/app/[locale]/[userId]/notifications/page.tsx b/src/app/[locale]/account/notifications/page.tsx
similarity index 100%
rename from src/app/[locale]/[userId]/notifications/page.tsx
rename to src/app/[locale]/account/notifications/page.tsx
diff --git a/src/app/[locale]/account/page.tsx b/src/app/[locale]/account/page.tsx
new file mode 100644
index 0000000..00d7154
--- /dev/null
+++ b/src/app/[locale]/account/page.tsx
@@ -0,0 +1,12 @@
+import { redirect, notFound } from 'next/navigation';
+// import { checkAuthToken } from '../../../utils/storage/auth';
+
+export default function AccountMainPage() {
+ // if (checkAuthToken()) {
+ // redirect('/sessions');
+ // } else {
+ // notFound();
+ // }
+
+ redirect('/sessions');
+};
diff --git a/src/app/[locale]/[userId]/sessions/page.tsx b/src/app/[locale]/account/sessions/page.tsx
similarity index 100%
rename from src/app/[locale]/[userId]/sessions/page.tsx
rename to src/app/[locale]/account/sessions/page.tsx
diff --git a/src/app/[locale]/[userId]/settings/change-password/page.tsx b/src/app/[locale]/account/settings/change-password/page.tsx
similarity index 100%
rename from src/app/[locale]/[userId]/settings/change-password/page.tsx
rename to src/app/[locale]/account/settings/change-password/page.tsx
diff --git a/src/app/[locale]/[userId]/settings/page.tsx b/src/app/[locale]/account/settings/page.tsx
similarity index 100%
rename from src/app/[locale]/[userId]/settings/page.tsx
rename to src/app/[locale]/account/settings/page.tsx
diff --git a/src/app/[locale]/[userId]/support/page.tsx b/src/app/[locale]/account/support/page.tsx
similarity index 100%
rename from src/app/[locale]/[userId]/support/page.tsx
rename to src/app/[locale]/account/support/page.tsx
diff --git a/src/app/[locale]/[userId]/work-with-us/page.tsx b/src/app/[locale]/account/work-with-us/page.tsx
similarity index 100%
rename from src/app/[locale]/[userId]/work-with-us/page.tsx
rename to src/app/[locale]/account/work-with-us/page.tsx
diff --git a/src/app/[locale]/bb-client/page.tsx b/src/app/[locale]/bb-client/page.tsx
new file mode 100644
index 0000000..9ffac83
--- /dev/null
+++ b/src/app/[locale]/bb-client/page.tsx
@@ -0,0 +1,197 @@
+import React from 'react';
+import type { Metadata } from 'next';
+import { useTranslations } from 'next-intl';
+import { GeneralTopSection } from '../../../components/Page';
+
+export const metadata: Metadata = {
+ title: 'Bbuddy - Take the lead with BB',
+ description: 'Bbuddy desc Take the lead with BB'
+};
+
+export default function BbClientPage() {
+ const t = useTranslations('BbClient');
+
+ return (
+ <>
+
+
+
+
How do you want to advance today?
+
+
Work - Life Balance
+
Personal growth
+
Career planning
+
Executive coaching
+
Financial thinking
+
Business development
+
Startup
+
Strategic session
+
Relationships
+
Healthy lifestyle
+
Relocation
+
+
+
+
+
+
Start the path to big goals with us
+
+
+
+
+
+
+
Take advantage of coaching sessions to help you grow
+ confidently by enhancing your skills and personal qualities.
+
+
Allow our professionals to use their expertise to assist
+ you in making a difference.
+
+
Develop the required skills and steer clear of common
+ pitfalls by working with a mentor.
+
+
Learn new things to equip yourself with cutting-edge
+ resources for advancement.
+
+
Communicate with like-minded people to get even more out of
+ B BUDDY.
+
+
+
+
+
+
+
+
+
B Buddy: Reliable and convenient
+
+
+
+
+
from 300 hours
+
experience of each coach
+
+
+
+
+
+
25 countries
+
+
location of participants
+
+
+
+
+
+
+
15 criteria
+
use B BUDDY to find the best mentor
+
+
+
+
+
+
+
5 minutes
+
from registering to speaking with an expert
+
+
+
+
+
+
+
+
+
+
+
+
+
All in one
+
+ Whether it's self-evaluation, public speaking, or
+ financial planning, B BUDDY can provide the support you need in one single
+ application. Now your smartphone has even more room for stunning photos.
+
+
+
+
The solution is right in your pocket
+
+ Get expert help as soon as you need it. A smartphone is
+ always within reach. Your competitive advantage is speed.
+
+
+
+
Focus on your top priorities
+
+ Make a call, schedule a meeting, set a reminder, and save
+ a link to a video conference. This can all be done with a single click using the
+ B BUDDY app. Let us take care of the rest while you focus on the things that
+ count.
+
+
+
+
+
+
+
+
+
+
+
+
+
B BUDDY will
+
+
+
+
+
Choose a professional who is a perfect fit for you
+
+
+
+
+
+
Set up meetings
+
+
+
+
+
+
Notify you in advance of the scheduled session
+
+
+
+
+
+
Invite you to a video call at the appropriate time
+
+
+
+
+
+
Isn’t that amazing?
+
+
+
+
+
+
+
+
+
Being formed by business owners and educators, B BUDDY is
+ completely aware of what is required and how to deliver it to you.
+
+
We work hard to support people in becoming more successful! We
+ therefore strive daily to make B BUDDY the top coaching, mentoring, and consulting
+ application.
+
+
+
+
+
+
+ >
+ );
+};
diff --git a/src/app/[locale]/bb-expert/page.tsx b/src/app/[locale]/bb-expert/page.tsx
new file mode 100644
index 0000000..5309f6e
--- /dev/null
+++ b/src/app/[locale]/bb-expert/page.tsx
@@ -0,0 +1,129 @@
+import React from 'react';
+import type { Metadata } from 'next';
+import { useTranslations } from 'next-intl';
+import { GeneralTopSection } from '../../../components/Page';
+import { ScreenCarousel } from '../../../components/Page/ScreenCarousel/index';
+
+export const metadata: Metadata = {
+ title: 'Bbuddy - Become a BB expert',
+ description: 'Bbuddy desc Become a BB expert'
+};
+
+export default function BbExpertPage() {
+ const t = useTranslations('BbExpert');
+
+ return (
+ <>
+
+
+
+
+
Everything you need in one application
+
+
+
+
+
+
+
+ Customer search
+
+
+ The application algorithm will match your profile data to the customer’s
+ request and recommend the best option. BB customers will come directly
+ to you!
+
+
+
+
+
+
+
+ Automation of appointments
+
+
+ Create your work schedule only once. Customers will make their own
+ appointments thereafter selecting a time slot on your calendar.
+
+
+
+
+
+
+
+ Video calls
+
+
+ Call up directly in B Buddy at the touch of a button. No more flicking
+ through apps in search of a link. A gentle reminder required? We will
+ send one.
+
+
+
+
+
+
+
+ Legal security
+
+
All required documents, including the contract
+ and consent to the processing of personal data, have been verified and
+ are available in the app.
+
+
+
+
+
+
+
+ Feedback
+
+
Gather feedback from all the customers in one
+ place. B Buddy will remind the customer to leave feedback after the
+ meeting is over.
+
+
+
+
+
+
+
+
+
+
+
B Buddy expert has:
+
+
+
+
+
From 300 hours
+
Coaching practice
+
+
+
+
+
+
From 5 years
+
Professional experience
+
+
+
+
+
+
Expertise
+
Confirmed by successfully implemented projects
+
+
+
+
+
+
+ >
+ );
+};
diff --git a/src/app/[locale]/news/[newsId]/page.tsx b/src/app/[locale]/blog/[newsId]/page.tsx
similarity index 100%
rename from src/app/[locale]/news/[newsId]/page.tsx
rename to src/app/[locale]/blog/[newsId]/page.tsx
diff --git a/src/app/[locale]/news/page.tsx b/src/app/[locale]/blog/page.tsx
similarity index 100%
rename from src/app/[locale]/news/page.tsx
rename to src/app/[locale]/blog/page.tsx
diff --git a/src/app/[locale]/experts/page.tsx b/src/app/[locale]/experts/page.tsx
index ea273ab..33fa566 100644
--- a/src/app/[locale]/experts/page.tsx
+++ b/src/app/[locale]/experts/page.tsx
@@ -1,48 +1,37 @@
import React from 'react';
import type { Metadata } from 'next';
+import { getTranslations } from 'next-intl/server';
+import { getFilter } from '../../../utils/filter';
import { getExpertsList } from '../../../actions/experts';
-import { ExpertsFilter } from '../../../components/Experts/Filter';
-import { ExpertsAdditionalFilter } from '../../../components/Experts/AdditionalFilter';
-import { ExpertsList } from '../../../components/Experts/ExpertsList';
-import { CustomPagination } from '../../../components/view';
+import { getTagList } from '../../../actions/tags';
+import { Experts } from '../../../components/Experts/Experts';
export const metadata: Metadata = {
title: 'Bbuddy - Experts',
description: 'Bbuddy desc experts'
};
-export default async function Experts({ params, searchParams }: { params: { locale: string }, searchParams: { [key: string]: string | string[] | undefined } }) {
- console.log('search params', searchParams);
- const data = await getExpertsList({
- "themesTagIds": [
- 1,2,3,4,5,6,7,8
- ],
- "priceFrom": null,
- "priceTo": null,
- "durationFrom": null,
- "durationTo": null
- }, params.locale);
+export default async function ExpertsPage({ params, searchParams }: { params: { locale: string }, searchParams: { [key: string]: string | string[] | undefined } }) {
+ const searchData = await getTagList(params.locale);
+ const filter = getFilter(searchData, searchParams);
+ console.log('filter experts page', filter);
+ const experts = await getExpertsList(filter, params.locale);
+ const t = await getTranslations('Experts');
return (
-
Find a expert
+
{t('title')}
-
+
diff --git a/src/app/[locale]/faq/page.tsx b/src/app/[locale]/faq/page.tsx
index edd8209..36c1287 100644
--- a/src/app/[locale]/faq/page.tsx
+++ b/src/app/[locale]/faq/page.tsx
@@ -8,8 +8,82 @@ export const metadata: Metadata = {
export default function Faq() {
return (
-
- Страница faq
-
+ <>
+
+
+
+
+
Frequently asked questions
+
+ Do you have any questions? Call!
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ How much will I earn for the consultation?
+
+
+ It is entirely up to you because you set the price for the services.
+
+
+
+
+
+
+
+ What will BBuddy’s commission be?
+
+
+ B Buddy will receive 15% commission of the consultation cost.
+
+
+
+
+
+
+
+ Can I bring my customer?
+
+
+ You will be able to invite existing customers to the application via a
+ unique link. B Buddy will not charge a fee for transferring your
+ existing customers.
+
+
+
+
+
+
+
+ What about if I introduce a new expert to B Buddy?
+
+
+ Within two months of the date of his platform registration, you will
+ receive 5% of each of his consultations.
+
+
+
+
+
+
+
+
+ >
);
-}
+};
diff --git a/src/app/[locale]/privacy-policy/page.tsx b/src/app/[locale]/privacy-policy/page.tsx
deleted file mode 100644
index 00908f2..0000000
--- a/src/app/[locale]/privacy-policy/page.tsx
+++ /dev/null
@@ -1,15 +0,0 @@
-import React from 'react';
-import type { Metadata } from 'next';
-
-export const metadata: Metadata = {
- title: 'Bbuddy - Privacy Policy',
- description: 'Bbuddy desc search'
-};
-
-export default function PrivacyPolicy() {
- return (
-
- Privacy policy
-
- );
-}
diff --git a/src/components/Experts/AdditionalFilter.tsx b/src/components/Experts/AdditionalFilter.tsx
index 18eb916..b039f69 100644
--- a/src/components/Experts/AdditionalFilter.tsx
+++ b/src/components/Experts/AdditionalFilter.tsx
@@ -1,51 +1,85 @@
'use client';
import React, { useCallback, useState } from 'react';
-import { Select } from 'antd';
+import {Button, Select} from 'antd';
+import { useSearchParams } from 'next/navigation';
+import { useRouter } from '../../navigation';
import { AdditionalFilter } from '../../types/experts';
-import { INITIAL_ADD_FILTER } from '../../constants/experts';
import { LOCALES } from '../../constants/locale';
+import { getObjectByFilter, getObjectByAdditionalFilter } from '../../utils/filter';
import { CustomInput } from '../view';
-export const ExpertsAdditionalFilter = () => {
- const [filter, setFilter] = useState(INITIAL_ADD_FILTER);
+type ExpertAdditionalFilterProps = {
+ searchPlaceholder: string;
+ sortLabel: string;
+ langLabel: string;
+ buttonFind: string;
+ basePath?: string;
+};
+
+export const ExpertsAdditionalFilter = ({
+ searchPlaceholder,
+ sortLabel,
+ langLabel,
+ buttonFind,
+ basePath = '/',
+}): ExpertAdditionalFilterProps => {
+ const searchParams = useSearchParams();
+ const router = useRouter();
+ const [filter, setFilter] = useState(getObjectByAdditionalFilter(searchParams));
const onChangeFilter = useCallback((key: string, value: any) => {
- setFilter({
- ...filter,
- [key]: value
- })
+ // setFilter({
+ // ...filter,
+ // [key]: value
+ // })
}, [filter]);
+ const goToFilterPage = useCallback(() => {
+ router.push({
+ pathname: basePath,
+ query: {
+ ...getObjectByFilter(searchParams),
+ ...filter
+ }
+ })
+ }, [filter, searchParams]);
+
return (
onChangeFilter('text', e?.target?.value)}
/>
onChangeFilter('sort', val)}
options={[
- { value: 'By top views', label: 'By top views' },
- { value: 'By Price Ascending', label: 'By Price Ascending' },
- { value: 'By Price Descending', label: 'By Price Descending' },
- { value: 'By rating', label: 'By rating' }
+ { value: 'byTop', label: 'By top views' },
+ { value: 'byPriceAsc', label: 'By price ascending' },
+ { value: 'byPriceDesc', label: 'By price descending' },
+ { value: 'byRating', label: 'By rating' }
]}
/>
onChangeFilter('language', val)}
options={Object.entries(LOCALES).map(([ value, label ]) => ({ value, label }))}
/>
-
Find
+
+ {buttonFind}
+
);
};
diff --git a/src/components/Experts/Experts.tsx b/src/components/Experts/Experts.tsx
new file mode 100644
index 0000000..904058f
--- /dev/null
+++ b/src/components/Experts/Experts.tsx
@@ -0,0 +1,47 @@
+import React from 'react';
+import { useTranslations } from 'next-intl';
+import { SearchData } from '../../types/tags';
+import { ExpertsData } from '../../types/experts';
+import { ExpertsFilter } from './Filter';
+import { ExpertsAdditionalFilter } from './AdditionalFilter';
+import { ExpertsList } from './ExpertsList';
+import { CustomPagination } from '../view/CustomPagination';
+
+type ExpertsProps = {
+ searchData?: SearchData;
+ experts?: ExpertsData;
+};
+
+export const Experts = ({ searchData, experts }: ExpertsProps) => {
+ const t = useTranslations('Experts');
+
+ return (
+
+ )
+};
diff --git a/src/components/Experts/ExpertsList.tsx b/src/components/Experts/ExpertsList.tsx
index 65d5ce3..eef04e8 100644
--- a/src/components/Experts/ExpertsList.tsx
+++ b/src/components/Experts/ExpertsList.tsx
@@ -5,11 +5,22 @@ import { List, Tag } from 'antd';
import { RightOutlined } from '@ant-design/icons';
import Image from 'next/image';
import { Link } from '../../navigation';
-import { Locale } from '../../types/locale';
import { ExpertsData } from '../../types/experts';
-export const ExpertsList = ({ data, locale }: { data: ExpertsData, locale: string }) => {
- const isRus = locale === Locale.ru;
+type ExpertListProps = {
+ data: ExpertsData;
+ priceTitle: string;
+ durationTitle: string;
+ detailButton: string;
+};
+
+export const ExpertsList = ({
+ data,
+ priceTitle,
+ durationTitle,
+ detailButton
+}: ExpertListProps) => {
+ const getTitle = (str: string, value?: any): string => (value ? str.replace('0', value) : str);
return (
{`${item.name} ${item?.surname || ''}`}
- {`${item?.sessionCost}${isRus ? '₽' : '€'}`} / {`${item?.sessionDuration}${isRus ? 'мин' : 'min'}`}
+ {getTitle(priceTitle, item?.sessionCost)} / {getTitle(durationTitle, item?.sessionDuration)}
)}
@@ -55,7 +66,7 @@ export const ExpertsList = ({ data, locale }: { data: ExpertsData, locale: strin
{item?.description}
- Details
+ {detailButton}
diff --git a/src/components/Experts/Filter.tsx b/src/components/Experts/Filter.tsx
index f272454..3f55f0d 100644
--- a/src/components/Experts/Filter.tsx
+++ b/src/components/Experts/Filter.tsx
@@ -1,65 +1,97 @@
'use client';
import React, { useCallback, useState } from 'react';
-import { List } from 'antd';
-import { FilterType, INITIAL_FILTER } from '../../constants/experts';
+import { Button, List } from 'antd';
+import { useSearchParams } from 'next/navigation';
import { Filter } from '../../types/experts';
+import { SearchData, Tag } from '../../types/tags';
+import { useRouter } from '../../navigation';
+import { getObjectByFilter, getObjectByAdditionalFilter } from '../../utils/filter';
import { CustomSwitch, CustomSlider } from '../view';
-import {Locale} from "../../types/locale";
-const dataCoaching = [
- {
- key: FilterType.WorkLifeBalance,
- title: 'Work-life Balance'
- },
- {
- key: FilterType.StrategicSession,
- title: 'Strategic Session'
- },
- {
- key: FilterType.PersonalGrowth,
- title: 'Personal Growth'
- },
- {
- key: FilterType.PersonalGrowth,
- title: 'Career Planning'
- },
- {
- key: FilterType.ExecutiveCoaching,
- title: 'Executive Coaching'
- }
-];
+type ExpertsFilterProps = {
+ searchData: SearchData;
+ basePath?: string;
+ priceTitle: string;
+ durationTitle: string;
+ buttonApply: string;
+};
-const dataMentoring = [
- {
- key: FilterType.CareerDevelopment,
- title: 'Career Development'
- },
- {
- key: FilterType.Networking,
- title: 'Networking'
- }
-];
+export const ExpertsFilter = ({
+ searchData,
+ basePath = '/',
+ priceTitle,
+ durationTitle,
+ buttonApply
+}: ExpertsFilterProps) => {
+ const searchParams = useSearchParams();
+ const router = useRouter();
+ const [filter, setFilter] = useState(getObjectByFilter(searchParams));
-const dataConsultation = [
- {
- key: FilterType.BusinessModelReview,
- title: 'Business Model Review'
- }
-];
+ const onChangeTags = useCallback((id: number, checked: boolean) => {
+ let themesTagIds = filter?.themesTagIds || [];
-export const ExpertsFilter = ({ locale }: { locale: string }) => {
- const [filter, setFilter] = useState(INITIAL_FILTER);
- const isRus = locale === Locale.ru;
+ if (checked && !themesTagIds?.includes(id)) {
+ themesTagIds.push(id);
+ }
+
+ if (!checked && themesTagIds?.includes(id)) {
+ themesTagIds = themesTagIds.filter((tId) => tId != id);
+ }
- const onChangeFilter = useCallback((key: string, value: any) => {
setFilter({
...filter,
- [key]: value
- })
- }, [filter]);
+ themesTagIds
+ });
+ }, [filter, searchParams, searchData]);
- const getList = useCallback((data: any[]) => (
+ const onChangePrice = useCallback(([min, max]: number[]) => {
+ const newFilter: Filter = {
+ ...filter,
+ priceFrom: min,
+ priceTo: max
+ };
+
+ if (newFilter.priceFrom === searchData?.sessionCostMin) {
+ delete newFilter.priceFrom;
+ }
+
+ if (newFilter.priceTo === searchData?.sessionCostMax) {
+ delete newFilter.priceTo;
+ }
+
+ setFilter(newFilter);
+ }, [filter, searchParams, searchData]);
+
+ const onChangeDuration = useCallback(([min, max]: number[]) => {
+ const newFilter: Filter = {
+ ...filter,
+ durationFrom: min,
+ durationTo: max
+ };
+
+ if (newFilter.durationFrom === searchData?.sessionDurationMin) {
+ delete newFilter.durationFrom;
+ }
+
+ if (newFilter.durationTo === searchData?.sessionDurationMax) {
+ delete newFilter.durationTo;
+ }
+
+ setFilter(newFilter);
+ }, [filter, searchParams, searchData]);
+
+ const goToFilterPage = useCallback(() => {
+ router.push({
+ pathname: basePath,
+ query: {
+ ...filter,
+ ...getObjectByAdditionalFilter(searchParams)
+ }
+ })
+ }, [filter, searchParams, searchData]);
+
+ const getList = useCallback((data: Tag[]) => (
{
dataSource={data}
split={false}
style={{ width: '100%' }}
- renderItem={({ key, title }) => (
-
+ renderItem={({ id, name }) => (
+
-
{title}
+
{name}
onChangeFilter(key, checked)}
+ defaultChecked={filter?.themesTagIds?.includes(id) || false}
+ onChange={(checked: boolean) => onChangeTags(id, checked)}
/>
)}
/>
- ), [filter]);
+ ), [filter, searchParams, searchData]);
return (
-
Coaching
- {getList(dataCoaching)}
-
Mentoring
- {getList(dataMentoring)}
-
Business-consultation
- {getList(dataConsultation)}
-
{`Price from 45${isRus ? '₽' : '€'} to 170${isRus ? '₽' : '€'}`}
+ {searchData.themesGroups?.length && searchData.themesGroups.map(({ id, name, tags }) => (
+
+
{name}
+ {getList(tags)}
+
+ ))}
+
{priceTitle}
onChangeFilter(FilterType.Price, val)}
+ defaultValue={[filter?.priceFrom || searchData.sessionCostMin, filter?.priceTo || searchData.sessionCostMax]}
+ min={searchData.sessionCostMin}
+ max={searchData.sessionCostMax}
+ onChange={onChangePrice}
/>
-
{`Duration from 45${isRus ? 'мин' : 'min'} to 120${isRus ? 'мин' : 'min'}`}
+
{durationTitle}
onChangeFilter(FilterType.Duration, val)}
+ defaultValue={[filter?.durationFrom || searchData.sessionDurationMin, filter?.durationTo || searchData.sessionDurationMax]}
+ min={searchData.sessionDurationMin}
+ max={searchData.sessionDurationMax}
+ onChange={onChangeDuration}
/>
-
Apply
+
+ {buttonApply}
+
);
};
diff --git a/src/components/Modals/AuthModal.tsx b/src/components/Modals/AuthModal.tsx
index c8df254..f48f8a7 100644
--- a/src/components/Modals/AuthModal.tsx
+++ b/src/components/Modals/AuthModal.tsx
@@ -8,6 +8,7 @@ import { CloseOutlined } from '@ant-design/icons';
import { styled } from 'styled-components';
import { CustomInput } from '../view';
import { getAuth } from '../../actions/auth';
+import {setAuthToken} from "../../utils/storage/auth";
type AuthModalProps = {
open: boolean;
@@ -87,7 +88,10 @@ export const AuthModal: FC = ({
setIsLoading(true);
getAuth(login, password, paths[1])
.then(({ data }) => {
- console.log('jwt', data.jwtToken)
+ if (data.jwtToken) {
+ setAuthToken(data.jwtToken);
+ handleCancel();
+ }
})
.catch((error) => {
notification.error({
diff --git a/src/components/Page/Footer/index.tsx b/src/components/Page/Footer/index.tsx
index bbe4178..f1b53f0 100644
--- a/src/components/Page/Footer/index.tsx
+++ b/src/components/Page/Footer/index.tsx
@@ -1,7 +1,7 @@
import React from 'react';
+import Link from 'next/link';
import { useTranslations } from 'next-intl';
-import { Link } from '../../../navigation';
-import { FOOTER_ROUTES } from '../../../constants/routes';
+import { Link as IntlLink } from '../../../navigation';
export const Footer = () => {
const t = useTranslations('Footer');
@@ -35,9 +35,8 @@ export const Footer = () => {
- {FOOTER_ROUTES.map((item) => (
- {t(`menu.${item}`)}
- ))}
+ {t('menu.faq')}
+ {t(`menu.privacy-policy`)}
diff --git a/src/components/Page/GeneralTopSection/index.tsx b/src/components/Page/GeneralTopSection/index.tsx
new file mode 100644
index 0000000..5f85a8a
--- /dev/null
+++ b/src/components/Page/GeneralTopSection/index.tsx
@@ -0,0 +1,45 @@
+import React from 'react';
+
+type GeneralTopSectionProps = {
+ title: string;
+ description?: string;
+ mainImage: string;
+};
+
+export const GeneralTopSection = ({
+ title,
+ description,
+ mainImage
+}: GeneralTopSectionProps) => (
+
+
+
{title}
+
+ {description &&
{description}
}
+
+
+
+
+
+
+
+);
diff --git a/src/components/Page/Header/HeaderAuthLinks.tsx b/src/components/Page/Header/HeaderAuthLinks.tsx
index dc61b9c..6ffeaf8 100644
--- a/src/components/Page/Header/HeaderAuthLinks.tsx
+++ b/src/components/Page/Header/HeaderAuthLinks.tsx
@@ -4,10 +4,13 @@ import React, { FC, useState, useEffect } from 'react';
import { Button } from 'antd';
import { styled } from 'styled-components';
import { AuthModal } from '../../Modals/AuthModal';
+import {checkAuthToken} from "../../../utils/storage/auth";
+import {Link} from "../../../navigation";
type HeaderAuthLinksProps = {
enterTitle: string;
registerTitle: string;
+ accountTitle: string;
separatorClass?: string;
};
@@ -24,6 +27,7 @@ const LinkButton = styled(Button)`
export const HeaderAuthLinks: FC = ({
enterTitle,
registerTitle,
+ accountTitle,
separatorClass = 'b-header__nav__list__line'
}) => {
const [isOpenModal, setIsOpenModal] = useState(false);
@@ -40,33 +44,39 @@ export const HeaderAuthLinks: FC = ({
setIsOpenModal(true);
};
- return (
- <>
+ return checkAuthToken()
+ ? (
- onOpen('register')}
- >
- {registerTitle}
-
+ {accountTitle}
-
- |
-
-
- onOpen('enter')}
- >
- {enterTitle}
-
-
- setIsOpenModal(false)}
- mode={mode}
- updateMode={setMode}
- />
- >
+ )
+ : (
+ <>
+
+ onOpen('register')}
+ >
+ {registerTitle}
+
+
+
+ |
+
+
+ onOpen('enter')}
+ >
+ {enterTitle}
+
+
+ setIsOpenModal(false)}
+ mode={mode}
+ updateMode={setMode}
+ />
+ >
);
};
diff --git a/src/components/Page/Header/HeaderMenu.tsx b/src/components/Page/Header/HeaderMenu.tsx
index 0653e86..1731c81 100644
--- a/src/components/Page/Header/HeaderMenu.tsx
+++ b/src/components/Page/Header/HeaderMenu.tsx
@@ -5,14 +5,15 @@ type HeaderMenuProps = {
children: ReactNode;
enterTitle: string;
registerTitle: string;
+ accountTitle: string;
};
-export const HeaderMenu = ({ children, enterTitle, registerTitle }: HeaderMenuProps) => (
+export const HeaderMenu = ({ children, enterTitle, registerTitle, accountTitle }: HeaderMenuProps) => (
diff --git a/src/components/Page/Header/HeaderMobileMenu.tsx b/src/components/Page/Header/HeaderMobileMenu.tsx
index 54352fc..3a2f869 100644
--- a/src/components/Page/Header/HeaderMobileMenu.tsx
+++ b/src/components/Page/Header/HeaderMobileMenu.tsx
@@ -7,9 +7,10 @@ type HeaderMenuMobileProps = {
children: ReactNode;
enterTitle: string;
registerTitle: string;
+ accountTitle: string;
};
-export const HeaderMobileMenu: FC = ({ children, enterTitle, registerTitle }) => {
+export const HeaderMobileMenu: FC = ({ children, enterTitle, registerTitle, accountTitle }) => {
const [showMobileMenu, setShowMobileMenu] = useState(false);
return (
@@ -33,6 +34,7 @@ export const HeaderMobileMenu: FC = ({ children, enterTit
separatorClass="menu-mobile__header__nav__line"
enterTitle={enterTitle}
registerTitle={registerTitle}
+ accountTitle={accountTitle}
/>
diff --git a/src/components/Page/Header/index.tsx b/src/components/Page/Header/index.tsx
index 75000d6..1413497 100644
--- a/src/components/Page/Header/index.tsx
+++ b/src/components/Page/Header/index.tsx
@@ -30,13 +30,13 @@ export const Header: FC
= ({ locale }) => {
alt=""
/>
-
+
{routes}
-
+
{routes}
>
diff --git a/src/components/Page/ScreenCarousel/index.tsx b/src/components/Page/ScreenCarousel/index.tsx
new file mode 100644
index 0000000..eccf2ec
--- /dev/null
+++ b/src/components/Page/ScreenCarousel/index.tsx
@@ -0,0 +1,88 @@
+'use client';
+
+import React, { useState } from 'react';
+import Slider from 'react-slick';
+import 'slick-carousel/slick/slick.css';
+import 'slick-carousel/slick/slick-theme.css';
+
+const ScreenList = [
+ {
+ id: '1',
+ title: 'Plan your working hours',
+ screen: '/images/slider-1.png'
+ },
+ {
+ id: '2',
+ title: 'Accept customers applications',
+ screen: '/images/slider-2.png'
+ },
+ {
+ id: '3',
+ title: 'Make video calls',
+ screen: '/images/slider-3.png'
+ },
+ {
+ id: '4',
+ title: 'Keep statistics',
+ screen: '/images/slider-4.png'
+ },
+ {
+ id: '5',
+ title: 'Get paid',
+ screen: '/images/slider-5.png'
+ },
+ {
+ id: '6',
+ title: 'Plan your working hours',
+ screen: '/images/slider-1.png'
+ },
+ {
+ id: '7',
+ title: 'Accept customers applications',
+ screen: '/images/slider-2.png'
+ },
+ {
+ id: '8',
+ title: 'Make video calls',
+ screen: '/images/slider-3.png'
+ },
+ {
+ id: '9',
+ title: 'Keep statistics',
+ screen: '/images/slider-4.png'
+ },
+ {
+ id: '10',
+ title: 'Get paid',
+ screen: '/images/slider-5.png'
+ }
+];
+
+export const ScreenCarousel = () => {
+ const [title, setTitle] = useState(ScreenList[0].title);
+ const settings = {
+ dots: false,
+ autoplay: true,
+ infinite: true,
+ speed: 500,
+ slidesToShow: 5,
+ slidesToScroll: 1,
+ arrows: false,
+ afterChange: (current: number) => {
+ setTitle(ScreenList[current].title);
+ }
+ };
+
+ return (
+
+
{title}
+
+ {ScreenList.map(({ id, screen }) => (
+
+
+
+ ))}
+
+
+ );
+};
diff --git a/src/components/Page/index.ts b/src/components/Page/index.ts
index 13ce3a8..c732478 100644
--- a/src/components/Page/index.ts
+++ b/src/components/Page/index.ts
@@ -1,2 +1,3 @@
export * from './Header';
export * from './Footer';
+export * from './GeneralTopSection';
diff --git a/src/constants/common.ts b/src/constants/common.ts
index d8bee4d..b19517c 100644
--- a/src/constants/common.ts
+++ b/src/constants/common.ts
@@ -1 +1,2 @@
export const BASE_URL = process.env.NEXT_PUBLIC_SERVER_BASE_URL || 'https://api.bbuddy.expert/api';
+export const AUTH_TOKEN_KEY = 'bbuddy_token';
diff --git a/src/constants/experts.ts b/src/constants/experts.ts
deleted file mode 100644
index 0ae7096..0000000
--- a/src/constants/experts.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import { AdditionalFilter, Filter } from '../types/experts';
-import { LOCALES } from './locale';
-
-export enum FilterType {
- 'WorkLifeBalance' = 'workLifeBalance',
- 'StrategicSession' = 'strategicSession',
- 'PersonalGrowth' = 'personalGrowth',
- 'CareerPlaning' = 'careerPlaning',
- 'ExecutiveCoaching' = 'executiveCoaching',
- 'CareerDevelopment' = 'careerDevelopment',
- 'Networking' = 'networking',
- 'BusinessModelReview' = 'businessModelReview',
- 'Price' = 'price',
- 'Duration' = 'duration'
-}
-
-export const INITIAL_FILTER: Filter = {
- [FilterType.WorkLifeBalance]: false,
- [FilterType.StrategicSession]: false,
- [FilterType.PersonalGrowth]: false,
- [FilterType.CareerPlaning]: false,
- [FilterType.ExecutiveCoaching]: false,
- [FilterType.CareerDevelopment]: false,
- [FilterType.Networking]: false,
- [FilterType.BusinessModelReview]: false,
- [FilterType.Price]: [65, 170],
- [FilterType.Duration]: [60, 120]
-};
-
-export const INITIAL_ADD_FILTER: AdditionalFilter = {
- sort: 'By top views',
- language: Object.keys(LOCALES)
-};
diff --git a/src/constants/routes.ts b/src/constants/routes.ts
index dfba8ff..125bafe 100644
--- a/src/constants/routes.ts
+++ b/src/constants/routes.ts
@@ -1,2 +1 @@
-export const HEAD_ROUTES = ['faq', 'experts', 'news'];
-export const FOOTER_ROUTES = ['faq', 'privacy-policy'];
+export const HEAD_ROUTES = ['bb-client', 'bb-expert', 'blog'];
diff --git a/src/styles/_bb-clients.scss b/src/styles/_bb-clients.scss
new file mode 100644
index 0000000..84a6441
--- /dev/null
+++ b/src/styles/_bb-clients.scss
@@ -0,0 +1,136 @@
+.bb-client {
+ margin-top: 140px
+}
+
+.tag-list {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
+}
+
+.tag-item {
+ background: #fff;
+ border-radius: 62px;
+ margin: 12px 8px;
+ color: #5aadcc;
+ padding: 16px;
+ font-size: 1.5rem;
+}
+
+.b2 {
+ padding: 120px 0 80px;
+
+ h2 {
+ margin-bottom: 40px;
+ }
+}
+
+.b4 {
+ margin-bottom: 30px;
+
+ &-list {
+ margin-top: 200px;
+ margin-bottom: 200px;
+ }
+
+ &-item {
+ margin-bottom: 30px;
+ }
+
+ &-title {
+ font-size: 2rem;
+ color: #2c7873;
+ }
+
+ &-descr {
+ color: #003b46;
+ font-size: 1rem;
+ }
+}
+
+.b4-title, .b5-item {
+ margin-bottom: 20px;
+}
+
+.b5 {
+ position: relative;
+ margin-top: -65px;
+
+ &-item {
+ background: #fff;
+ height: calc(100% - 120px);
+ margin-top: 100px;
+ position: relative;
+ text-align: center;
+ padding: 120px 16px 16px;
+ border-radius: 16px;
+ margin-bottom: 20px;
+ }
+
+ &-img {
+ height: 204px;
+ width: auto;
+ top: 0;
+ left: 50%;
+ position: absolute;
+ -webkit-transform: translate(-50%, -50%);
+ -ms-transform: translate(-50%, -50%);
+ transform: translate(-50%, -50%);
+ }
+
+ &-text {
+ font-size: 1.5rem;
+ color: #5aadcc;
+ }
+
+ h3 {
+ margin: 36px 0;
+ font-size: 2rem;
+ color: #2c7873;
+ text-align: center;
+ }
+}
+
+.b6 {
+ margin: 60px 0 40px;
+
+ &-banner {
+ background: #ffd213;
+ border-radius: 16px;
+ padding: 0 32px;
+ display: flex;
+ -ms-flex-align: center;
+ align-items: center;
+ position: relative;
+
+ &:after {
+ position: absolute;
+ right: -70px;
+ top: -70px;
+ content: "";
+ width: 170px;
+ height: 170px;
+ display: block;
+ background: url(/images/white-ball.svg) center center no-repeat;
+ background-size: contain;
+ }
+ }
+
+ &-content {
+ width: 45%;
+ color: #2C7873;
+ }
+
+ &-title {
+ font-size: 2rem;
+ margin-bottom: 10px;
+ }
+
+ &-descr {
+ font-size: 1rem;
+ }
+
+ &-img {
+ width: 55%;
+ }
+}
diff --git a/src/styles/_bb-experts.scss b/src/styles/_bb-experts.scss
new file mode 100644
index 0000000..c29a91b
--- /dev/null
+++ b/src/styles/_bb-experts.scss
@@ -0,0 +1,120 @@
+.b-slider {
+ margin-top: -105px;
+
+ h2 {
+ margin: 40px 0 20px;
+ text-align: center;
+ }
+}
+
+.slider {
+ position: relative;
+ padding-bottom: 80px;
+ padding-top: 20px;
+ text-align: center;
+ overflow: hidden;
+
+ &:after {
+ content: "";
+ background: url(/images/slider-nahd.png) center center no-repeat;
+ left: 50%;
+ top: 20px;
+ width: 522px;
+ height: 522px;
+ position: absolute;
+ -webkit-transform: translate(-50%, -5px);
+ -ms-transform: translate(-50%, -5px);
+ transform: translate(-50%, -5px);
+ pointer-events: none;
+ }
+
+ &-item {
+ display: inline-flex !important;
+ justify-content: center;
+ }
+}
+
+.waves-top {
+ position: relative;
+ background: #DFF5FB;
+ margin-bottom: 24px;
+
+ &:before {
+ content: "";
+ position: absolute;
+ background-image: url(/images/wave-footer.svg);
+ background-position: center bottom;
+ background-size: contain;
+ background-repeat: repeat-x;
+ top: -59px;
+ width: 100%;
+ height: 59px;
+ }
+}
+
+.advice-list {
+ margin: 24px 0 40px;
+}
+
+.advice-item {
+ background: #E4F5FA;
+ border-radius: 16px;
+ margin-bottom: 24px;
+ padding: 16px;
+ font-size: 1.5rem;
+}
+
+.advice-item--with-img {
+ display: flex;
+ align-items: center;
+
+ .advice-img {
+ width: 148px;
+ min-width: 148px;
+ height: auto;
+ margin-right: 1rem;
+ }
+
+ .advice-title {
+ font-size: 2rem;
+ margin-bottom: 0.5rem;
+ }
+}
+
+.b3 {
+ margin-bottom: 40px;
+
+ &-item {
+ background: #e0f3f1;
+ height: calc(100% - 120px);
+ margin-bottom: 20px;
+ margin-top: 100px;
+ position: relative;
+ text-align: center;
+ padding: 120px 16px 16px;
+ border-radius: 16px;
+ }
+
+ &-img {
+ position: absolute;
+ height: 204px;
+ width: auto;
+ top: 0;
+ left: 50%;
+ -webkit-transform: translate(-50%, -50%);
+ -ms-transform: translate(-50%, -50%);
+ transform: translate(-50%, -50%);
+ }
+
+ &-title {
+ color: #000;
+ font-size: 1.5rem;
+ text-transform: uppercase;
+ margin-bottom: 14px;
+ }
+
+ &-text {
+ font-size: 1rem;
+ }
+}
+
diff --git a/src/styles/_default.scss b/src/styles/_default.scss
index fad40a2..96bf644 100644
--- a/src/styles/_default.scss
+++ b/src/styles/_default.scss
@@ -287,6 +287,10 @@ body{
align-items: flex-start;
width: 100%;
+ & > div {
+ width: 100%;
+ }
+
&__inner {
display: flex;
flex-direction: column;
@@ -321,6 +325,7 @@ body{
font-style: normal;
font-weight: 400;
line-height: 160%;
+ text-transform: capitalize;
}
}
@@ -440,6 +445,10 @@ body{
font-style: normal;
font-weight: 400;
line-height: 160%;
+
+ &:hover, &:active {
+ color: #003B46 !important;
+ }
}
.btn-back {
diff --git a/src/styles/_faq.scss b/src/styles/_faq.scss
new file mode 100644
index 0000000..b99f8c2
--- /dev/null
+++ b/src/styles/_faq.scss
@@ -0,0 +1,100 @@
+.banner {
+ text-align: center;
+ margin-bottom: -80px;
+
+ &-faq {
+ h1 {
+ font-size: 2.93rem;
+ margin-top: 120px;
+ color: #2C7873;
+ }
+ }
+
+ &-note {
+ font-size: 1.5rem;
+ color: #4e7c86;
+ }
+}
+
+.mb-4 {
+ margin-bottom: 1.5rem!important;
+}
+
+.store-buttons {
+ display: flex;
+ margin-bottom: 24px;
+}
+
+.store-button {
+ color: #fff;
+ font-size: 1.5rem;
+ line-height: 1.5rem;
+ text-decoration: none;
+ background: #5AADCC;
+ border-radius: 62px;
+ padding: 21px 15px 21px 73px;
+ margin: 0 12px;
+ transition: .3s all ease;
+ animation: pulse;
+ animation-duration: 2s;
+ position: relative;
+
+ &:before {
+ width: 32px;
+ height: 32px;
+ position: absolute;
+ left: 24px;
+ transform: translate(0, -50%);
+ }
+
+ &:after {
+ width: 1px;
+ height: 42px;
+ position: absolute;
+ left: 64px;
+ background: #fff;
+ transform: translate(0, -50%);
+ }
+
+ &:after, &:before {
+ display: block;
+ top: 50%;
+ content: "";
+ }
+
+ &.phone:before {
+ background: url(/images/call-outline-white.svg) center center no-repeat;
+ background-size: contain;
+ }
+}
+
+.mb-5 {
+ margin-bottom: 3rem!important;
+}
+
+.advice {
+ &-item {
+ background: #E4F5FA;
+ border-radius: 16px;
+ margin-bottom: 24px;
+ padding: 16px;
+ font-size: 1.5rem;
+
+ &--with-img {
+ display: flex;
+ align-items: center;
+ }
+ }
+
+ &-img {
+ width: 148px;
+ min-width: 148px;
+ height: auto;
+ margin-right: 1rem;
+ }
+
+ &-title {
+ font-size: 2rem;
+ margin-bottom: 0.5rem;
+ }
+}
diff --git a/src/styles/style.scss b/src/styles/style.scss
index cc358e9..2322f18 100644
--- a/src/styles/style.scss
+++ b/src/styles/style.scss
@@ -4,6 +4,9 @@
@import "_header.scss";
@import "_menu-mobile.scss";
@import "_main.scss";
+@import "_bb-experts.scss";
+@import "_bb-clients.scss";
+@import "_faq.scss";
@import "_footer.scss";
@import "_cols.scss";
@import "_pages.scss";
diff --git a/src/types/experts.ts b/src/types/experts.ts
index 2f48836..fb2d0bb 100644
--- a/src/types/experts.ts
+++ b/src/types/experts.ts
@@ -1,12 +1,16 @@
-export type Filter = Record;
+import { Tag } from './tags';
-// export type Filter = {
-// themesTagIds: number[];
-// priceFrom?: number | null;
-// priceTo?: number | null;
-// durationFrom?: number | null;
-// durationTo?: number | null;
-// };
+// export type Filter = Record;
+
+export type GeneralFilter = Filter & AdditionalFilter;
+
+export type Filter = {
+ themesTagIds?: number[];
+ priceFrom?: number | null;
+ priceTo?: number | null;
+ durationFrom?: number | null;
+ durationTo?: number | null;
+};
export type AdditionalFilter = {
text?: string;
@@ -14,14 +18,6 @@ export type AdditionalFilter = {
language?: string[];
};
-export type Tag = {
- id: number;
- groupId: number;
- name: string
- couchCount?: number;
- group?: string | null;
-};
-
export type File = {
id: number;
fileType: string;
diff --git a/src/types/tags.ts b/src/types/tags.ts
new file mode 100644
index 0000000..20b0b2b
--- /dev/null
+++ b/src/types/tags.ts
@@ -0,0 +1,21 @@
+export type Tag = {
+ id: number;
+ groupId: number;
+ name: string
+ couchCount?: number;
+ group?: string | null;
+};
+
+export type ThemeGroups = {
+ id: number;
+ name: string;
+ tags: Tag[];
+};
+
+export type SearchData = {
+ themesGroups: ThemeGroups[],
+ sessionCostMin: number;
+ sessionCostMax: number;
+ sessionDurationMin: number;
+ sessionDurationMax: number;
+};
diff --git a/src/utils/filter.ts b/src/utils/filter.ts
new file mode 100644
index 0000000..286d279
--- /dev/null
+++ b/src/utils/filter.ts
@@ -0,0 +1,103 @@
+import { SearchData } from '../types/tags';
+import { AdditionalFilter, Filter } from '../types/experts';
+
+export const getDefaultFilter = (searchData: SearchData | null): Filter => {
+ const themesTagIds = searchData?.themesGroups?.reduce((result, { tags }) => {
+ const t = tags?.map(({ id }) => id) || [];
+
+ return t ? [
+ ...result,
+ ...t
+ ] : result;
+ }, []);
+
+ return {
+ themesTagIds,
+ priceFrom: null,
+ priceTo: null,
+ durationFrom: null,
+ durationTo: null
+ } as Filter;
+};
+
+export const getFilter = (searchData: SearchData | null, searchParams?: { [key: string]: string | string[] | undefined }): Filter => {
+ const filter = getDefaultFilter(searchData);
+
+ if (searchParams) {
+ const { themesTagIds, priceFrom, priceTo, durationFrom, durationTo } = searchParams;
+
+ if (themesTagIds) {
+ if (Array.isArray(themesTagIds) && themesTagIds?.length > 0) {
+ filter.themesTagIds = themesTagIds.map((id) => +id);
+ }
+
+ if (typeof themesTagIds === 'string') {
+ filter.themesTagIds = [+themesTagIds];
+ }
+ }
+
+ if (priceFrom) {
+ filter.priceFrom = +priceFrom;
+ }
+
+ if (priceTo) {
+ filter.priceTo = +priceTo;
+ }
+
+ if (durationFrom) {
+ filter.durationFrom = +durationFrom;
+ }
+
+ if (durationTo) {
+ filter.durationTo = +durationTo;
+ }
+ }
+
+ return filter;
+};
+
+export const getObjectByFilter = (searchParams?: any): Filter | undefined => {
+ const filter: Filter = {};
+
+ let tags = searchParams?.getAll('themesTagIds');
+
+ if (tags && tags.length > 0) {
+ filter.themesTagIds = tags.map((id) => Number(id));
+ }
+
+ if (searchParams?.has('priceFrom')) {
+ filter.priceFrom = Number(searchParams.get('priceFrom'));
+ }
+
+ if (searchParams?.has('priceTo')) {
+ filter.priceTo = Number(searchParams.get('priceTo'));
+ }
+
+ if (searchParams?.has('durationFrom')) {
+ filter.durationFrom = Number(searchParams.get('durationFrom'));
+ }
+
+ if (searchParams?.has('durationTo')) {
+ filter.durationTo = Number(searchParams.get('durationTo'));
+ }
+
+ return filter;
+};
+
+export const getObjectByAdditionalFilter = (searchParams?: any): AdditionalFilter => {
+ const additionalFilter: AdditionalFilter = {};
+
+ if (searchParams?.has('text')) {
+ additionalFilter.text = searchParams.get('text');
+ }
+
+ if (searchParams?.has('sort')) {
+ additionalFilter.sort = searchParams.get('sort');
+ }
+
+ if (searchParams?.has('language')) {
+ additionalFilter.language = searchParams.getAll('language');
+ }
+
+ return additionalFilter;
+};
diff --git a/src/utils/storage/auth.ts b/src/utils/storage/auth.ts
new file mode 100644
index 0000000..9b2696f
--- /dev/null
+++ b/src/utils/storage/auth.ts
@@ -0,0 +1,23 @@
+'use client';
+
+import { AUTH_TOKEN_KEY } from '../../constants/common';
+
+export function checkAuthToken() {
+ return !!getAuthToken();
+}
+
+export function getAuthToken() {
+ return 'tr';
+}
+
+// export function getAuthToken() {
+// return localStorage.getItem(AUTH_TOKEN_KEY);
+// }
+//
+// export function removeAuthToken() {
+// localStorage.removeItem(AUTH_TOKEN_KEY);
+// }
+//
+// export function setAuthToken(token: string) {
+// localStorage.setItem(AUTH_TOKEN_KEY, token);
+// }