diff --git a/src/App.js b/src/App.js index cca685c..00aa6ea 100644 --- a/src/App.js +++ b/src/App.js @@ -1,18 +1,24 @@ import React from 'react'; -import Header from './components/Header/Header'; -import SkinTypeQuiz from './components/SkinTypeQuiz/SkinTypeQuiz'; +import Header from './components/Header/Header'; +import SkinTypeQuiz from './components/SkinTypeQuiz/SkinTypeQuiz'; +import PopularProducts from './components/PopularProducts/PopularProducts'; import './App.css'; function App() { return (
-
+
-

Добро пожаловать в SkinCare Advisor!

- +

+ Добро пожаловать в SkinCare Advisor! +

+
+ +
+
); } -export default App; \ No newline at end of file +export default App; diff --git a/src/components/PopularProducts/PopularProducts.css b/src/components/PopularProducts/PopularProducts.css new file mode 100644 index 0000000..f4d889d --- /dev/null +++ b/src/components/PopularProducts/PopularProducts.css @@ -0,0 +1,77 @@ +.popular-products { + max-width: 1200px; + margin: 40px auto; + padding: 0 20px; + } + + .popular-products h2 { + text-align: center; + margin-bottom: 40px; + font-size: 28px; + } + + .products-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(270px, 1fr)); + gap: 30px; + } + + .product-card { + border: 1px solid #eee; + border-radius: 12px; + overflow: hidden; + transition: transform 0.3s; + } + + .product-card:hover { + transform: translateY(-5px); + } + + .product-image { + width: 100%; + height: 200px; + object-fit: cover; + } + + .product-card h3 { + padding: 15px 15px 0; + margin: 0; + font-size: 18px; + } + + .product-card p { + padding: 10px 15px; + color: #666; + font-size: 14px; + margin: 0; + } + + .product-footer { + padding: 15px; + display: flex; + justify-content: space-between; + align-items: center; + } + + .price { + font-weight: bold; + color: #333; + } + + .details-btn { + background: #f8f9fa; + border: 1px solid #ddd; + padding: 8px 15px; + border-radius: 20px; + cursor: pointer; + transition: all 0.3s; + opacity: 0; /* Скрываем кнопку по умолчанию */ + } + + .product-card:hover .details-btn { + background: #6C63FF; + color: white; + border-color: #6C63FF; + opacity: 1; /* Показываем кнопку при наведении */ + } + \ No newline at end of file diff --git a/src/components/PopularProducts/PopularProducts.js b/src/components/PopularProducts/PopularProducts.js new file mode 100644 index 0000000..d78f515 --- /dev/null +++ b/src/components/PopularProducts/PopularProducts.js @@ -0,0 +1,64 @@ +import React from 'react'; +import './PopularProducts.css'; +import product1 from './img/product1.jpg'; +import product2 from './img/product2.jpg'; +import product3 from './img/product3.jpg'; +import product4 from './img/product4.jpg'; + +const products = [ + { + id: 1, + name: "Гиалуроновый крем", + image: product1, + description: "Интенсивное увлажнение на 24 часа", + price: "1 490 ₽" + }, + { + id: 2, + name: "Сыворотка с витамином С", + image: product2, + description: "Освежает и выравнивает тон кожи", + price: "2 350 ₽" + }, + { + id: 3, + name: "Мицеллярная вода", + image: product3, + description: "Мгновенно удаляет макияж", + price: "890 ₽" + }, + { + id: 4, + name: "Ночной крем", + image: product4, + description: "Восстановление во время сна", + price: "1 950 ₽" + } +]; + +function PopularProducts() { + return ( +
+

Популярные косметические средства

+
+ {products.map(product => ( +
+ {product.name} +

{product.name}

+

{product.description}

+
+ {product.price} + +
+
+ ))} +
+
+ ); +} + +export default PopularProducts; diff --git a/src/components/PopularProducts/img/product1.jpg b/src/components/PopularProducts/img/product1.jpg new file mode 100644 index 0000000..046ca42 Binary files /dev/null and b/src/components/PopularProducts/img/product1.jpg differ diff --git a/src/components/PopularProducts/img/product2.jpg b/src/components/PopularProducts/img/product2.jpg new file mode 100644 index 0000000..1b44ad6 Binary files /dev/null and b/src/components/PopularProducts/img/product2.jpg differ diff --git a/src/components/PopularProducts/img/product3.jpg b/src/components/PopularProducts/img/product3.jpg new file mode 100644 index 0000000..2b79a80 Binary files /dev/null and b/src/components/PopularProducts/img/product3.jpg differ diff --git a/src/components/PopularProducts/img/product4.jpg b/src/components/PopularProducts/img/product4.jpg new file mode 100644 index 0000000..f46ab62 Binary files /dev/null and b/src/components/PopularProducts/img/product4.jpg differ diff --git a/src/components/SkinTypeQuiz/Question.js b/src/components/SkinTypeQuiz/Question.js index e69de29..d45ee23 100644 --- a/src/components/SkinTypeQuiz/Question.js +++ b/src/components/SkinTypeQuiz/Question.js @@ -0,0 +1,118 @@ +import React, { useState, useEffect } from 'react'; + +function Question({ question, answer, onAnswer, isLast, onNext }) { + const [selected, setSelected] = useState(() => { + return question.type === 'multiple' + ? Array.isArray(answer) ? [...answer] : [] + : answer || ''; + }); + + const [otherText, setOtherText] = useState(''); + + // Инициализация otherText + useEffect(() => { + if (question.type === 'multiple' && Array.isArray(answer)) { + const otherItem = answer.find(item => item?.other); + setOtherText(otherItem?.otherText || ''); + } + }, [answer, question.type]); + + // Синхронизация с пропсом answer + useEffect(() => { + if (question.type === 'multiple') { + setSelected(Array.isArray(answer) ? answer : []); + } else { + setSelected(typeof answer === 'string' ? answer : ''); + } + }, [answer, question.type]); + + const handleChange = (option, isOther = false) => { + if (question.type === 'single') { + setSelected(option); + onAnswer(question.id, option); + return; + } + + let newSelected = Array.isArray(selected) ? [...selected] : []; + + if (isOther) { + const existingOther = newSelected.findIndex(item => item?.other); + if (existingOther >= 0) { + newSelected.splice(existingOther, 1); + setOtherText(''); + } else { + newSelected.push({ other: true, otherText: '' }); + } + } else { + const index = newSelected.findIndex(item => item === option); + if (index >= 0) { + newSelected.splice(index, 1); + } else { + newSelected.push(option); + } + } + + setSelected(newSelected); + onAnswer(question.id, newSelected); + }; + + const handleOtherTextChange = (e) => { + const text = e.target.value; + setOtherText(text); + const newSelected = (Array.isArray(selected) ? selected : []).map(item => { + return item?.other ? { ...item, otherText: text } : item; + }); + setSelected(newSelected); + onAnswer(question.id, newSelected); + }; + + const handleSubmit = (e) => { + e.preventDefault(); + onNext(); + }; + + const safeSelected = question.type === 'multiple' + ? (Array.isArray(selected) ? selected : []) + : selected; + + return ( +
+

{question.text}

+
+ {question.options.map(option => { + const isOther = option.toLowerCase().includes('другое'); + const isChecked = question.type === 'multiple' + ? isOther + ? safeSelected.some(item => item?.other) + : safeSelected.includes(option) + : safeSelected === option; + + return ( +
+ + {isOther && safeSelected.some(item => item?.other) && ( + + )} +
+ ); + })} +
+ +
+ ); +} + +export default Question; diff --git a/src/components/SkinTypeQuiz/Result.js b/src/components/SkinTypeQuiz/Result.js index e69de29..70e7abf 100644 --- a/src/components/SkinTypeQuiz/Result.js +++ b/src/components/SkinTypeQuiz/Result.js @@ -0,0 +1,12 @@ +import React from 'react'; + +function Result({ recommendations }) { + return ( +
+

Результаты опроса

+

{recommendations}

+
+ ); +} + +export default Result; diff --git a/src/components/SkinTypeQuiz/SkinTypeQuiz.css b/src/components/SkinTypeQuiz/SkinTypeQuiz.css index e69de29..f4a8b7c 100644 --- a/src/components/SkinTypeQuiz/SkinTypeQuiz.css +++ b/src/components/SkinTypeQuiz/SkinTypeQuiz.css @@ -0,0 +1,34 @@ +form { + max-width: 600px; + margin: 20px auto; + padding: 20px; + background-color: #fafafa; + border: 1px solid #ddd; + border-radius: 8px; + box-shadow: 0 0 8px rgba(0,0,0,0.1); + font-family: Arial, sans-serif; + } + + h3 { + margin-bottom: 16px; + } + + label { + cursor: pointer; + } + + button { + margin-top: 20px; + padding: 10px 24px; + background-color: #007bff; + border: none; + color: white; + font-size: 16px; + border-radius: 6px; + cursor: pointer; + } + + button:hover { + background-color: #0056b3; + } + \ No newline at end of file diff --git a/src/components/SkinTypeQuiz/SkinTypeQuiz.js b/src/components/SkinTypeQuiz/SkinTypeQuiz.js index 3af5353..bf662b8 100644 --- a/src/components/SkinTypeQuiz/SkinTypeQuiz.js +++ b/src/components/SkinTypeQuiz/SkinTypeQuiz.js @@ -1,53 +1,104 @@ -import React from 'react'; +import React, { useState } from 'react'; +import Question from './Question'; +import Result from './Result'; import './SkinTypeQuiz.css'; -import Question from './Question.js'; -import Result from './Result.js'; -const quiz = [ - { - id: 1, - text: "Ваш пол?", - type: "single", - options: ["Мужской", "Женcкий",] - }, - { - id: 2, - text: "Сколько вам лет?", - type: "single", - options: ["Менее 18", "18-25", "26-35", "36-45", , "46-55", "Более 55"] - }, - { - id: 3, - text: "Опишите кожу сразу после умывания:", - type: "single", - options: ["Сухая и тянущаяся", "Нормальная, без ощущения сухости или жирности", "Жирная, блестящая", " Комбинированная (нормальная на щеках, жирная на Т-зоне)"] - }, - { - id: 4, - text: "Как часто вы испытываете раздражение или покраснение кожи?", - type: "single", - options: ["Часто", "Редко", "Практически никогда"] - }, - { - id: 5, - text: "Как вы оцениваете чувствительность вашей кожи?", - type: "single", - options: ["Очень чувствительная", "Средняя чувствительность", "Мало чувствительная"] - }, - { - id: 6, - text: "Какие проблемы с кожей вас беспокоят? (выберите все, что применимо)", - type: "multiple", - options: ["Акне", "Черные точки", "Пигментация", "Морщины", "Другое (укажите)"] - }, - { - id: 7, - text: "Какие косметические средства вы обычно используете? (выберите все, что применимо)", - type: "multiple", - options: ["Крем для лица", "Сыворотка", "Маска", "Тональный крем", "Другое (укажите)"] +const questionsMock = [ + { + id: 1, + text: "Ваш пол?", + type: "single", + options: ["Мужской", "Женcкий"] + }, + { + id: 2, + text: "Сколько вам лет?", + type: "single", + options: ["Менее 18", "18-25", "26-35", "36-45", "46-55", "Более 55"] + }, + { + id: 3, + text: "Опишите кожу сразу после умывания:", + type: "single", + options: ["Сухая и тянущаяся", "Нормальная, без ощущения сухости или жирности", "Жирная, блестящая", "Комбинированная (нормальная на щеках, жирная на Т-зоне)"] + }, + { + id: 4, + text: "Как часто вы испытываете раздражение или покраснение кожи?", + type: "single", + options: ["Часто", "Редко", "Практически никогда"] + }, + { + id: 5, + text: "Как вы оцениваете чувствительность вашей кожи?", + type: "single", + options: ["Очень чувствительная", "Средняя чувствительность", "Мало чувствительная"] + }, + { + id: 6, + text: "Какие проблемы с кожей вас беспокоят? (выберите все, что применимо)", + type: "multiple", + options: ["Акне", "Черные точки", "Пигментация", "Морщины", "Другое (укажите)"] + }, + { + id: 7, + text: "Какие косметические средства вы обычно используете? (выберите все, что применимо)", + type: "multiple", + options: ["Крем для лица", "Сыворотка", "Маска", "Тональный крем", "Другое (укажите)"] + } +]; + +function SkinTypeQuiz() { + const [currentIndex, setCurrentIndex] = useState(0); + const [answers, setAnswers] = useState({}); + const [showResult, setShowResult] = useState(false); + const [recommendations, setRecommendations] = useState(''); + + const questions = questionsMock; + + const handleAnswer = (questionId, answer) => { + const currentQuestion = questions.find(q => q.id === questionId); + const safeAnswer = currentQuestion.type === 'multiple' + ? Array.isArray(answer) ? answer : [] + : answer; + + setAnswers(prev => ({ ...prev, [questionId]: safeAnswer })); + }; + + const handleNext = () => { + if (currentIndex + 1 < questions.length) { + setCurrentIndex(currentIndex + 1); + } else { + const rec = calculateRecommendations(answers); + setRecommendations(rec); + setShowResult(true); } -] + }; + if (showResult) { + return ; + } + return ( + + ); +} -export default SkinTypeQuiz; \ No newline at end of file +function calculateRecommendations(answers) { + const question3Answer = answers[3]; // ID=3 — вопрос про тип кожи + if (question3Answer === 'Сухая и тянущаяся') { + return 'Рекомендуется использовать увлажняющие средства и средства для чувствительной кожи.'; + } + if (question3Answer === 'Жирная, блестящая') { + return 'Рекомендуется использовать средства для жирной кожи и против акне.'; + } + return 'Рекомендуется использовать базовый уход за кожей.'; +} + +export default SkinTypeQuiz;