Нужно срочно сдать сайт "заметки" слева как вы видите будет список заметок, снизу кнопка для их создания, справа вверху поле ввода для названия заметок, оно уже вместе с названием слева в списке, справа кнопка сохранить, а ниже поле ввода текста. Всю ночь верстал, а сейчас через 2 часа уже нужно сдавать проект в колледж, нужно заставить это работать через state manager для сохранения в local storage. Вот скрин как это должно было выглядеть Пацаны, помогите Я если что далеко не программист, код строго не судите Вся ночь ушла что бы тупо сверстать сам код import React, { useState, useEffect } from 'react'; import './App.css'; // Файл стилей для компонента function App() { const [noteName, setNoteName] = useState('Название заметки'); // Используем useState для отслеживания изменений текста noteName const [noteBase, setNoteBase] = useState(''); // Используем useState для отслеживания изменений текста noteBase const [currentDate, setCurrentDate] = useState(''); // Используем useState для отслеживания текущей даты const handleNoteNameChange = (event) => { setNoteName(event.target.value); // Обновляем noteName при изменении значения в input }; const handleNoteBaseChange = (event) => { setNoteBase(event.target.value); // Обновляем noteBase при изменении значения в textarea }; useEffect(() => { const today = new Date(); const options = { year: 'numeric', month: 'long', day: 'numeric' }; setCurrentDate(today.toLocaleDateString('ru-RU', options)); }, []); return ( <div className="App"> <div className="background"> <div className="outerRectangle"> <div className="innerRectangle"> <div className="wintree"> <input className="noteName" type="text" value={noteName} onChange={handleNoteNameChange} /> <div className="savebt"> <span className="savebt-text">Сохранить</span> </div> </div> <textarea className="notebase" // Добавляем класс для стилизации value={noteBase} onChange={handleNoteBaseChange} placeholder="Введите вашу заметку здесь" // Добавляем placeholder для подсказки пользователю /> <div className="dateText"> {currentDate} </div> </div> <div className="textOverlay"> <span className="firstLine">One</span> <span className="secondLine">Note</span> </div> <div className="noteBlock"> <span className="noteNameInBlock">{noteName}</span> </div> <div className="newnote"> <span className="newnote-text">+ новая заметка</span> </div> </div> </div> </div> ); } export default App; JS import React, { useState, useEffect } from 'react'; import './App.css'; // Файл стилей для компонента function App() { const [noteName, setNoteName] = useState('Название заметки'); // Используем useState для отслеживания изменений текста noteName const [noteBase, setNoteBase] = useState(''); // Используем useState для отслеживания изменений текста noteBase const [currentDate, setCurrentDate] = useState(''); // Используем useState для отслеживания текущей даты const handleNoteNameChange = (event) => { setNoteName(event.target.value); // Обновляем noteName при изменении значения в input }; const handleNoteBaseChange = (event) => { setNoteBase(event.target.value); // Обновляем noteBase при изменении значения в textarea }; useEffect(() => { const today = new Date(); const options = { year: 'numeric', month: 'long', day: 'numeric' }; setCurrentDate(today.toLocaleDateString('ru-RU', options)); }, []); return ( <div className="App"> <div className="background"> <div className="outerRectangle"> <div className="innerRectangle"> <div className="wintree"> <input className="noteName" type="text" value={noteName} onChange={handleNoteNameChange} /> <div className="savebt"> <span className="savebt-text">Сохранить</span> </div> </div> <textarea className="notebase" // Добавляем класс для стилизации value={noteBase} onChange={handleNoteBaseChange} placeholder="Введите вашу заметку здесь" // Добавляем placeholder для подсказки пользователю /> <div className="dateText"> {currentDate} </div> </div> <div className="textOverlay"> <span className="firstLine">One</span> <span className="secondLine">Note</span> </div> <div className="noteBlock"> <span className="noteNameInBlock">{noteName}</span> </div> <div className="newnote"> <span className="newnote-text">+ новая заметка</span> </div> </div> </div> </div> ); } export default App; body { background-color: #1E1E1E; /* Цвет фона */ margin: 0; /* Убираем отступы по умолчанию у body */ height: 100vh; /* Занимает всю высоту видимой области окна браузера */ display: flex; /* Используем флексбокс для центрирования */ justify-content: center; /* Выравнивание по горизонтали по центру */ align-items: center; /* Выравнивание по вертикали по центру */ } .App { text-align: center; } .outerRectangle { width: 1252px; /* Ширина внешнего прямоугольника */ height: 665px; /* Высота внешнего прямоугольника */ background-color: #EEEEEE; /* Цвет внешнего прямоугольника */ border-radius: 40px; /* Закругление углов внешнего прямоугольника */ padding: 25px; /* Отступы внутри внешнего прямоугольника */ position: relative; /* Позиционирование для внутреннего прямоугольника */ } .innerRectangle { width: 961px; /* Ширина внутреннего прямоугольника */ height: 665px; /* Высота внутреннего прямоугольника */ background-color: #FFFFFF; /* Цвет внутреннего прямоугольника */ border-top-left-radius: 21px; /* Закругление верхнего левого угла */ border-bottom-left-radius: 5px; /* Закругление нижнего левого угла */ border-top-right-radius: 21px; /* Закругление верхнего правого угла */ border-bottom-right-radius: 21px; /* Закругление нижнего правого угла */ position: absolute; /* Абсолютное позиционирование внутреннего прямоугольника */ top: 25px; /* Отступ сверху */ right: 25px; /* Отступ справа */ } .wintree { width: 961px; /* Ширина прямоугольника */ height: 60px; /* Высота прямоугольника */ background-color: #DCDCDC; /* Цвет прямоугольника */ border-top-left-radius: 21px; /* Закругление верхнего левого угла */ border-top-right-radius: 21px; /* Закругление верхнего правого угла */ position: absolute; /* Абсолютное позиционирование прямоугольника */ top: 0px; /* Поднимаем прямоугольник на высоту wintree, чтобы он находился на верхней границе innerRectangle */ left: 0; /* Выравниваем слева */ } /* ...другие стили... */ .textOverlay { position: absolute; top: 40px; /* Отступ сверху */ left: 37px; /* Отступ слева */ font-size: 32px; /* Размер текста */ font-family: 'Inter', sans-serif; /* Шрифт */ font-weight: 800; /* Толщина шрифта (extrabold) */ color: #0A0A0A; /* Цвет текста */ text-align: left; /* Выравнивание по левому краю */ line-height: 1.2; /* Межстрочный интервал */ } .firstLine { display: block; /* Размещаем текст на новой строке */ } .secondLine { display: block; /* Размещаем текст на новой строке */ } /* ...другие стили... */ .wintree { /* ...другие стили wintree... */ position: relative; } .noteName { /* ...другие стили noteName... */ font-size: 20px; /* Размер текста */ font-family: 'Inter', sans-serif; /* Шрифт */ font-weight: 600; /* Толщина шрифта (semi-bold) */ color: #000000; /* Цвет текста */ position: absolute; top: 50%; /* Позиционируем по вертикали внутри wintree */ left: 25px; /* Отступ слева */ transform: translateY(-50%); /* Центрируем по вертикали внутри wintree */ background: none; /* Убираем фон */ border: none; /* Убираем рамку */ outline: none; /* Убираем контур при фокусе */ } /* ...другие стили... */ .noteBlock { position: absolute; top: 150px; /* Поднимаем блок на нужное расстояние под текстом */ left: 35px; /* Выравниваем по левому краю */ width: 228px; /* Ширина блока */ height: 34px; /* Высота блока */ background-color: #FFFFFF; /* Цвет блока */ border-radius: 10px; /* Закругление углов блока */ box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1); /* Тень блока */ display: flex; /* Используем flexbox для центрирования текста */ align-items: center; /* Выравниваем текст по центру по вертикали */ padding: 0 10px; /* Добавляем отступы по бокам */ } .noteNameInBlock { font-size: 20px; /* Размер текста */ color: #000000; /* Цвет текста */ font-family: 'Inter', sans-serif; /* Устанавливаем шрифт Inter */ font-weight: 600; /* Устанавливаем полужирное начертание */ white-space: nowrap; /* Запрещаем перенос строк */ overflow: hidden; /* Скрываем все, что выходит за границы блока */ text-overflow: ellipsis; /* Вместо скрытого текста добавляем многоточие */ max-width: 100%; /* Ограничиваем максимальную ширину */ text-align: center; /* Выравниваем текст по центру */ } /* ...другие стили... */ .newnote { position: absolute; bottom: 25px; /* Располагаем блок снизу */ left: 27px; /* Отступ слева */ width: 270px; /* Ширина блока */ height: 58px; /* Высота блока */ background-color: #D9D9D9; /* Цвет блока */ border-top-left-radius: 10px; /* Закругление верхнего левого угла */ border-bottom-left-radius: 22px; /* Закругление нижнего левого угла */ border-top-right-radius: 5px; /* Закругление верхнего правого угла */ border-bottom-right-radius: 5px; /* Закругление нижнего правого угла */ display: flex; /* Используем flexbox для центрирования текста по вертикали и горизонтали */ justify-content: center; /* Выравниваем по горизонтали по центру */ align-items: center; /* Выравниваем по вертикали по центру */ } .newnote-text { font-size: 20px; /* Размер текста */ color: #000000; /* Цвет текста */ font-family: 'Inter', sans-serif; /* Устанавливаем шрифт Inter */ font-weight: 600; /* Устанавливаем полужирное начертание */ } .notebase { width: calc(80% - 40px); /* Ширина поля с учетом отступов слева и справа */ height: 80%; /* Высота поля */ margin: 20px 20px 20px -150px; /* Отступы: сверху, справа, снизу, слева */ resize: none; /* Запрещаем изменение размера поля */ padding: 10px; /* Внутренние отступы */ border-radius: 10px; /* Закругление углов поля */ font-size: 16px; /* Размер текста */ font-family: 'Inter', sans-serif; /* Шрифт */ color: #000000; /* Цвет текста */ border: none; /* Убираем границу */ outline: none; /* Убираем контур при фокусе */ } .dateText { position: absolute; top: 90px; /* Отступ сверху */ right: 30px; /* Отступ справа */ font-size: 16px; /* Размер текста */ font-family: 'Inter', sans-serif; /* Шрифт */ color: #909090; /* Цвет текста */ } .wintree { position: relative; /* Установка позиции как относительной для корректного позиционирования внутренних элементов */ } .savebt { position: absolute; /* Абсолютное позиционирование */ top: 0px; /* Отступ сверху */ right: 0px; /* Отступ справа */ width: 155px; /* Ширина блока */ height: 60px; /* Высота блока */ border-top-left-radius: 21px; /* Закругление верхнего левого угла */ border-top-right-radius: 21px; /* Закругление верхнего правого угла */ border-bottom-right-radius: 0; /* Закругление нижнего правого угла */ border-bottom-left-radius: 0; /* Закругление нижнего левого угла */ background-color: #ffffff; /* Цвет блока */ display: flex; /* Используем flexbox для центрирования текста */ justify-content: center; /* Выравнивание по горизонтали по центру */ align-items: center; /* Выравнивание по вертикали по центру */ } .savebt-text { font-size: 16px; /* Размер текста */ color: #000000; /* Цвет текста */ font-family: 'Inter', sans-serif; /* Устанавливаем шрифт Inter */ font-weight: 600; /* Устанавливаем полужирное начертание */ } CSS body { background-color: #1E1E1E; /* Цвет фона */ margin: 0; /* Убираем отступы по умолчанию у body */ height: 100vh; /* Занимает всю высоту видимой области окна браузера */ display: flex; /* Используем флексбокс для центрирования */ justify-content: center; /* Выравнивание по горизонтали по центру */ align-items: center; /* Выравнивание по вертикали по центру */ } .App { text-align: center; } .outerRectangle { width: 1252px; /* Ширина внешнего прямоугольника */ height: 665px; /* Высота внешнего прямоугольника */ background-color: #EEEEEE; /* Цвет внешнего прямоугольника */ border-radius: 40px; /* Закругление углов внешнего прямоугольника */ padding: 25px; /* Отступы внутри внешнего прямоугольника */ position: relative; /* Позиционирование для внутреннего прямоугольника */ } .innerRectangle { width: 961px; /* Ширина внутреннего прямоугольника */ height: 665px; /* Высота внутреннего прямоугольника */ background-color: #FFFFFF; /* Цвет внутреннего прямоугольника */ border-top-left-radius: 21px; /* Закругление верхнего левого угла */ border-bottom-left-radius: 5px; /* Закругление нижнего левого угла */ border-top-right-radius: 21px; /* Закругление верхнего правого угла */ border-bottom-right-radius: 21px; /* Закругление нижнего правого угла */ position: absolute; /* Абсолютное позиционирование внутреннего прямоугольника */ top: 25px; /* Отступ сверху */ right: 25px; /* Отступ справа */ } .wintree { width: 961px; /* Ширина прямоугольника */ height: 60px; /* Высота прямоугольника */ background-color: #DCDCDC; /* Цвет прямоугольника */ border-top-left-radius: 21px; /* Закругление верхнего левого угла */ border-top-right-radius: 21px; /* Закругление верхнего правого угла */ position: absolute; /* Абсолютное позиционирование прямоугольника */ top: 0px; /* Поднимаем прямоугольник на высоту wintree, чтобы он находился на верхней границе innerRectangle */ left: 0; /* Выравниваем слева */ } /* ...другие стили... */ .textOverlay { position: absolute; top: 40px; /* Отступ сверху */ left: 37px; /* Отступ слева */ font-size: 32px; /* Размер текста */ font-family: 'Inter', sans-serif; /* Шрифт */ font-weight: 800; /* Толщина шрифта (extrabold) */ color: #0A0A0A; /* Цвет текста */ text-align: left; /* Выравнивание по левому краю */ line-height: 1.2; /* Межстрочный интервал */ } .firstLine { display: block; /* Размещаем текст на новой строке */ } .secondLine { display: block; /* Размещаем текст на новой строке */ } /* ...другие стили... */ .wintree { /* ...другие стили wintree... */ position: relative; } .noteName { /* ...другие стили noteName... */ font-size: 20px; /* Размер текста */ font-family: 'Inter', sans-serif; /* Шрифт */ font-weight: 600; /* Толщина шрифта (semi-bold) */ color: #000000; /* Цвет текста */ position: absolute; top: 50%; /* Позиционируем по вертикали внутри wintree */ left: 25px; /* Отступ слева */ transform: translateY(-50%); /* Центрируем по вертикали внутри wintree */ background: none; /* Убираем фон */ border: none; /* Убираем рамку */ outline: none; /* Убираем контур при фокусе */ } /* ...другие стили... */ .noteBlock { position: absolute; top: 150px; /* Поднимаем блок на нужное расстояние под текстом */ left: 35px; /* Выравниваем по левому краю */ width: 228px; /* Ширина блока */ height: 34px; /* Высота блока */ background-color: #FFFFFF; /* Цвет блока */ border-radius: 10px; /* Закругление углов блока */ box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1); /* Тень блока */ display: flex; /* Используем flexbox для центрирования текста */ align-items: center; /* Выравниваем текст по центру по вертикали */ padding: 0 10px; /* Добавляем отступы по бокам */ } .noteNameInBlock { font-size: 20px; /* Размер текста */ color: #000000; /* Цвет текста */ font-family: 'Inter', sans-serif; /* Устанавливаем шрифт Inter */ font-weight: 600; /* Устанавливаем полужирное начертание */ white-space: nowrap; /* Запрещаем перенос строк */ overflow: hidden; /* Скрываем все, что выходит за границы блока */ text-overflow: ellipsis; /* Вместо скрытого текста добавляем многоточие */ max-width: 100%; /* Ограничиваем максимальную ширину */ text-align: center; /* Выравниваем текст по центру */ } /* ...другие стили... */ .newnote { position: absolute; bottom: 25px; /* Располагаем блок снизу */ left: 27px; /* Отступ слева */ width: 270px; /* Ширина блока */ height: 58px; /* Высота блока */ background-color: #D9D9D9; /* Цвет блока */ border-top-left-radius: 10px; /* Закругление верхнего левого угла */ border-bottom-left-radius: 22px; /* Закругление нижнего левого угла */ border-top-right-radius: 5px; /* Закругление верхнего правого угла */ border-bottom-right-radius: 5px; /* Закругление нижнего правого угла */ display: flex; /* Используем flexbox для центрирования текста по вертикали и горизонтали */ justify-content: center; /* Выравниваем по горизонтали по центру */ align-items: center; /* Выравниваем по вертикали по центру */ } .newnote-text { font-size: 20px; /* Размер текста */ color: #000000; /* Цвет текста */ font-family: 'Inter', sans-serif; /* Устанавливаем шрифт Inter */ font-weight: 600; /* Устанавливаем полужирное начертание */ } .notebase { width: calc(80% - 40px); /* Ширина поля с учетом отступов слева и справа */ height: 80%; /* Высота поля */ margin: 20px 20px 20px -150px; /* Отступы: сверху, справа, снизу, слева */ resize: none; /* Запрещаем изменение размера поля */ padding: 10px; /* Внутренние отступы */ border-radius: 10px; /* Закругление углов поля */ font-size: 16px; /* Размер текста */ font-family: 'Inter', sans-serif; /* Шрифт */ color: #000000; /* Цвет текста */ border: none; /* Убираем границу */ outline: none; /* Убираем контур при фокусе */ } .dateText { position: absolute; top: 90px; /* Отступ сверху */ right: 30px; /* Отступ справа */ font-size: 16px; /* Размер текста */ font-family: 'Inter', sans-serif; /* Шрифт */ color: #909090; /* Цвет текста */ } .wintree { position: relative; /* Установка позиции как относительной для корректного позиционирования внутренних элементов */ } .savebt { position: absolute; /* Абсолютное позиционирование */ top: 0px; /* Отступ сверху */ right: 0px; /* Отступ справа */ width: 155px; /* Ширина блока */ height: 60px; /* Высота блока */ border-top-left-radius: 21px; /* Закругление верхнего левого угла */ border-top-right-radius: 21px; /* Закругление верхнего правого угла */ border-bottom-right-radius: 0; /* Закругление нижнего правого угла */ border-bottom-left-radius: 0; /* Закругление нижнего левого угла */ background-color: #ffffff; /* Цвет блока */ display: flex; /* Используем flexbox для центрирования текста */ justify-content: center; /* Выравнивание по горизонтали по центру */ align-items: center; /* Выравнивание по вертикали по центру */ } .savebt-text { font-size: 16px; /* Размер текста */ color: #000000; /* Цвет текста */ font-family: 'Inter', sans-serif; /* Устанавливаем шрифт Inter */ font-weight: 600; /* Устанавливаем полужирное начертание */ }
maloy_inc Привет! Я готов помочь с твоей проблемой. Давай разберемся с твоим кодом. Для начала, ты уже создал state manager для сохранения в local storage?
maloy_inc, Прошу прощения, если возникли проблемы. Я готов помочь с кодом, если у тебя возникли трудности.
Ну у тебя тут очень простая логика, чатгпт справится чтоб написать, просто давай ему описание подробнее какую фичу тебе добавить надо и весь код кидай (кроме стилей) Ну или напиши конкретно с чем помочь, весь код писать за тебя тоже никто не будет
maloy_inc, для сохранения в localStorage измени handleSave const handleSave = () => { // Создаем новый объект заметки const newNote = { name: noteName, content: noteBase, date: currentDate }; // Обновляем массив заметок, добавляя новую заметку в начало списка const updatedNotes = [newNote, ...notesArray]; setNotesArray(updatedNotes); // Сохраняем обновленный массив заметок в localStorage localStorage.setItem('notes', JSON.stringify(updatedNotes)); }; JS const handleSave = () => { // Создаем новый объект заметки const newNote = { name: noteName, content: noteBase, date: currentDate }; // Обновляем массив заметок, добавляя новую заметку в начало списка const updatedNotes = [newNote, ...notesArray]; setNotesArray(updatedNotes); // Сохраняем обновленный массив заметок в localStorage localStorage.setItem('notes', JSON.stringify(updatedNotes)); }; и в хуке useEffect подгружай из localStorage данные эти useEffect(() => { const savedNotes = JSON.parse(localStorage.getItem('notes')); if (savedNotes) { setNotesArray(savedNotes); } }, []); JS useEffect(() => { const savedNotes = JSON.parse(localStorage.getItem('notes')); if (savedNotes) { setNotesArray(savedNotes); } }, []); бля полетело форматирование кода почему-то, короче по такой логике запросы к чатугпт составь и он выдаст готовое решение тебе
maloy_inc, ну и для дива с заметками поменяй стили, добавь прокрутку ему если слишком много контента .savedNotes { height: 300px; /* Пример высоты, установите значение по вашему усмотрению */ overflow-y: auto; /* Включаем вертикальную прокрутку */ } CSS .savedNotes { height: 300px; /* Пример высоты, установите значение по вашему усмотрению */ overflow-y: auto; /* Включаем вертикальную прокрутку */ }