Интернет магазин (pet-проект)
Привет! Давайте поговорим о заказах онлайн! Ведь все мы хоть раз заказывали какие-либо товары по интернету. Сейчас век технологий, не надо никуда ходить, чтобы совершать покупки. Все можно делать из дому! На этот раз я сделал сайт, посвященный – как вы уже поняли – интернет-магазину.
Основные моменты этого сайта:
При регистрации у каждого пользователя в базе данных появляется массив с корзиной и избранным . Также есть роль . По умолчанию это обычный пользователь, но также есть и роль Admin , которая позволяет создавать, редактировать и удалять товары. Эту роль, конечно же, нельзя самостоятельно выбрать, ее можно только поменять в самой базе данных. Да, я решил не делать возможность создавать товары, их редактировать или удалять по имейлу или телефону , я сделал эту возможность исключительно по роли. Так намного эффективнее!
Создавать товар может только человек с ролью Admin, что логично. При создании товара можно сделать описание товара, его имя, указать цену, сделать характеристики товара и т.д. Можно также редактировать товар и удалять его.
Тут я также, как и в прошлом проекте, использовал модульный тип стилей. Помимо этого, я визуально отделял блоки стилей у классов по их типу.
Я много вариантов (два) перепробовал загружать товары в корзину. Первый был легкий способ, он подразумевал получение полного объекта товара и загрузки его в корзину пользователя. Но у этого способа есть несколько минусов. Первый минус - это то, что объект массива может быть большим и из-за этого и объект пользователя растет многократно. Второй и самый основной недостаток - это то, что мы загружаем крайнюю версию товара, и если данные о товаре поменяются (например, цена), то у пользователя все останется так, как это было в тот момент, когда он добавил товар в корзину. Из-за этого я пришел ко второму способу. Более сложному, но в то же время эффективному. Я загружал в объект пользователя сами id товара. С этим не возникло никаких проблем. Первые проблемы появились при преобразовании этих id товаров в полноценный объект. Первое, что я придумал, так это сделать map по корзине пользователя и при каждой итерации раскрывать этот id в объект товара и добавлять его в массив со всеми товарами пользователя. Но во-первых, этот метод был очень костыльным, а во-вторых, он выводил только первый элемент из массива id'шников. Далее, порыскав в интернете, я нашел метод в используемой мной базе данных, который позволял доставать определенные объекты с помощью передаваемого в него массива с нужными нам элементами, которые стоит найти. Код я написал (скопировал и вставил) без особых проблем, как и проверил его в программе вызова этих функций (insomnia). Там он отработал успешно. Главные проблемы появились на фронтенде. Я пытался передавать body со всеми данными, но в ответ получал пустой массив. Помучавшись, я решил передать вместо body параметры с этим массивом. В ответ я уже получил долгожданный массив с объектами товаров!
Помимо корзины также есть и страница с избранным. Принцип тот же, что и у корзины. Только там уже нет подсчета общей стоимости товаров и их количества. Если товар уже лежит в избранном, то вы можете его убрать, кликнув еще 1 раз на значок с сердечком. И аналогично добавить его в избранное.
Для ховер-эффектов добавил такой функционал, что он отрабатывает только до определенного размера страницы, чтобы не было залипания ховер-эффекта на мобильных устройствах.
Сделал Сортировку товаров по количеству отзывов, по цене и по названию. Принцип таков, что у нас изначально имеется объект с элементом, по которому мы должны сортировать, и значения 1 и -1 для того, чтобы база данных поняла, в каком направлении ей сортировать массив. Мы передаем массив с этими двумя элементами, а потом срезаем при помощи ссылок эти 2 элемента и передаем на бэкэнд. Там я создал проверку, по какому принципу сортировать (если по просмотрам, то по просмотрам сортируем, если по цене, то по цене соответственно). Хотел сделать это при помощи ссылок в ключе, например, req.params.item: '123', но к сожалению, подобная запись выдавала ошибку.
P.S. Я уже исправил этот недочет, и сейчас все работает в короткой записи.
После того как мы обработали массив и отправили на фронтенд, в главном файле при помощи useEffect отлавливаем изменение получаемого массива, и если там произошли изменения, то мы добавляем в useState новый массив для последующего доставания из этого массива товаров, который ищет пользователь. Может, я это воплотил в реальность немного костыльно... (на мой взгляд), но это работает.
Также, рядом с сортировкой, расположилась группировка всех товаров. Все товары можно группировать как список или как блоки. Блочный тип более компактный и позволяет рассмотреть больше товаров на каждой линии товаров, но у этого типа группировки не отображаются отзывы. У группировки типа "list" все в точности, да наоборот.
У каждого товара есть личная страница, где вы можете рассмотреть все подробности о нем. У личной страницы товара присутствуют: изображения товаров и внедренный в них слайдер для прокрутки и просмотра фотографий, описание, кол-во отзывов, цена, различные отзывы, а также нижний раздел с характеристиками и разделом с отзывами.
Про отзывы. В отзывах присутствуют такие обязательные поля, как достоинства, недостатки, и необязательное поле в виде добавления картинок. Максимум, сколько можно добавить картинок, это 3. Сделано это для того, чтобы не спамили ими и не нагружали сервер.
После написания кода для отзывов как на бэкэнде, так и на фронтенде, я упустил одну маленькую, но очень важную деталь - это общая оценка товара. Я попросту забыл добавить эту функцию. Я решил себя не утруждать этим и не делать данную возможность, как ни как, проект учебный, а не реальный.
Вы не можете оставить больше одного отзыва. При заходе на страницу с отзывами, идет проверка, есть ли пользователь в списке отзывов, если есть, то поле с созданием отзыва просто не отображается. Поле с созданием отзыва также не будет отображаться, если пользователь не купил данный товар.
При добавлении товара в корзину, он логично появляется в корзине, и его цена суммируется со всеми товарами в корзине. Вы можете перейти к оформлению заказа. Конечно, я не стал делать реальную возможность заказать товары, потому что это не представляется возможным на данный момент :/ Но я сделал так, что при нажатии на оформление заказа, мне на почту присылается список ваших товаров, их общая цена, а также ваши личные данные, которые вы указали при оформлении заказа.
На странице оформления заказа присутствует карта с рандомным местом в Москве... не знаю зачем это, но пусть будет.
Я хотел сделать форму отправки email'ов на бэкэнде, но там нужно было вводить пароль от почты. От своей почты пароль я давать не хочу (даже если в .env файле), а создавать специально новую почту тоже не хочется. В итоге остановился на старом добром EmailJS.
Поиск товаров осуществляется при помощи встроенной в JS функции filter. Он сначала ищет по названию, если не удалось найти по названию товара, то он начинает искать по типу товаров (например, video card). Если и тут ничего не удалось найти, то выходит сообщение с уведомлением об этом.
Над главной страницей особо не парился. Есть блоки с товарами, кликая на которых вы автоматически переходите в каталог с этой категорией товара. Есть также баннер, чтобы главная страница не была уж прям пустой.
Возможно, я упустил некоторые функции. За всеми фишками не уследишь. Я делал этот сайт без конкретного плана, делал все то, что приходило мне в голову.
Над дизайном особо не парился, весь упор старался делать в функционал. За основу дизайна брал магазин DNS, но что-то добавлял и от себя.
P.S. Если в каталоге у вас ничего не отоброжается, то стоит подождать или перезагрузить страницу. Т.к. хостинг базы данных бесплатный, его скорость урезана
Сам сайт находится по ссылке: https://zerostorage.vercel.app/
Репозиторий проекта: https://github.com/ItsZeroFour/zerostorage/tree/main
Другое:
Vercal(хостинг клиентской части): https://vercel.com/
Render(хостинг серверной части): https://render.com/
MongoDB(база данных): https://www.mongodb.com/
EmailJS(отправка email): https://www.emailjs.com/загруз