Skip to content

GlebTheProgrammer/Car-sharing-center

Repository files navigation

SamSolutions Project - Car Sharing Center (21 марта 2023 г.)

Основная идея проеат: Разработать приложение-сервис каршеринговой службы с отображением доступных автомобилей на карте. По содержанию - всё, что можно сопоставить с сущностью Vehicles: Автомобили, мотоциклы, любые транспортные средства и тд. Приложение должно быть многофункциональным: Необходимо наличие большого числа страниц с возможностью получать, добавлять, изменять и удалять сущности.

История коммитов с пояснением

  • 12 октября 2022 - Начало проекта.
  • 13 октября 2022 - Начало работы с главной страницей и страницей каталога. Составление структуры моделей.
  • 15 октября 2022 - Добавление GoogleMaps API. Начало работы со страницами регистрации и входа.
  • 18 октября 2022 - Рефакторинг + работа со страницей добавления своего автомобиля в каталог.
  • 24 октября 2022 - Рефакторинг. Сериализация и десериализация. Доработка страницы и логики добавления своего автомобиля.
  • 25 октября 2022 - Работа со страницей каталога. Добавление pager-а на страницу.
  • 26-28 октября 2022 - Работа с аутентификацией пользователя на основе сессий и httpContextAccessor.
  • 31 октября 2022 - Отказ от работы с сессиями в связи с большим количеством контроллеров. Переход с сессий на объект хранения статуса UserStatusProvider. Добавление JS сообщений с использованием сервиса SweetAlert2.
  • 1 ноября 2022 - Тестирование сервиса, добавление информации на страницу. Доработка страницы добавления своего автомобиля.
  • 2 ноября 2022 - Добавление страницы с информацией об автомобиле из каталога. Добавление логики контроля доступа для неавторизованного пользователя.
  • 3-4 ноября 2022 - Работа с ReadMe.
  • 10-16 ноября 2022 - Продумывание идеи оформления заказов. Реализация страницы пользователя с частичным функционалом (неполным).
  • 17 ноября 2022 - Рефакторинг.
  • 19 ноября 2022 - Работа с кабинетом пользователя. Полностью реализовал функционал редактирования информации пользователя. Начал делать страницу редактирования автомобилей.
  • 20 ноября 2022 - Рефакторинг. Доделал страницу редактирования информации об автомобиле.
  • 21 ноября 2022 - Подключение в тестовом режиме платёжного сервиса Stripe к проекту. Добавление функционала выбора времени и даты на страницу с оформлением заказа.
  • 23 ноября 2022 - Доделал часть с оформлением заказа. Поменял расположение JS кода (разнёс по файлам).
  • 26 ноября 2022 - Доделал часть с отслеживанием просроченных заказов.
  • 28 ноября 2022 - Добавление сообщений об успешных действиях пользователя. Добавил в каталоге возможность видеть всем пользователям время с последнего заказа того или иного автомобиля. Добавил возможность на странице с информацией об автомобиле из каталога посмотерть так называемое Brief Description аккаунта разместившего автомобиль пользователя. Начал делать часть с выставлением рейтинга для автомобилей.
  • 30 ноября 2022 - Закончил делать часть с выставлением рейтинга для автомобилей (когда пользователь завершает активный заказ на автомобиль из своего личного кабинета). Небольшой рефакторинг.
  • 2 декабря 2022 - Переход на .NET 7. Работа над поисковой системой страницы каталога.
  • 3 декабря 2022 - Замена огромного количества разных репозиториев одним RepositoryProvider и сведение всей функциональности под него.
  • 5 декабря 2022 - Добавление JWToken Authentication на контроллеры Web-приложения.
  • 8 декабря 2022 - Рефакторинг части с контроллерами и логики взаимодействия с ними.
  • 11 декабря 2022 - Работа с JWToken и настройка отображения страницы с ошибкой на стороне клиента.
  • 16 декабря 2022 - Рефакторинг с целью перехода от хранения информации в JSON-файлах к хранению в MongoDB Local.
  • 17 декабря 2022 - Настройка кластера MongoDB Atlas с целью дальнейшей работы с облачным сервисом.
  • 19 декабря 2022 - Рефакторинг. Работа над UI. Изменение маркера Google Maps API с красного на автомобиль с названием и изображением.

Официальное начало стажировки

  • 20 декабря 2022 - Переход от одного Web-приложения к полноценной Clean Architecture.
  • 21 декабря 2022 - Работа с Domain Layer и настройка первых моделей. Модели создаются в стиле Rich Domain Models заместо Anemic Domain Models.
  • 22 декабря 2022 - Работа с Application и Infrastructure Layers, а также настройка первых взаимодействий с сервисом и настройка DI.
  • 23 декабря 2022 - Связывание ранее созданных слоёв вместе с PublicAPI.
  • 24 декабря 2022 - Настройка первых endpoints и их ручное тестирование.
  • 25 декабря 2022 - Начало работы над Errors Handling и его обработки.
  • 26 декабря 2022 - Добавление Errors Handling в часть модели Vehicle.
  • 27 декабря 2022 - Создание контроллера пользователя и его тестирование на endpoints.
  • 28 декабря 2022 - Добавление функциональности Azure Key Vault для получения секретных данных с Azure. Внедрение битовых флагов как одного из вариантов хранения информации об автомобилях.
  • 30 декабря 2022 - Работа с критерими и ролями, а также добавление новых критериев валидации и привязывание к ним возможных ошибок.
  • 1 января 2023 - Добавление новых endpoints в CustomerController и их ручное тестирование.
  • 2 января 2023 - Добавление новых endpoints в VehicleController и их ручное тестирование.
  • 4 января 2023 - Редактирование моделей и сервисов.
  • 5 января 2023 - Добавление IHttpClientFactory для создания клиентов для отправки requests в сторону PublicAPI. Настройка Polly для недетерминированной отправке сообщений с возможностью их ожидания и повторной отправки в случае критических ситуаций.
  • 7 января 2023 - Настройка межпрограммной сериализации и десериализации (маршалинг и демаршалинг), а также сведение сообщений с ответом с сервера под отдельные сущности.
  • 8 января 2023 - Связывание PublicApi вместе с Web-частью и проверка endpoints и межпрограммной сериализации и десериализации.
  • 10 января 2023 - Работа над страницей входа и сохранение полученного JWToken с сервера на стороне клиента при успешном входе в аккаунт.
  • 11 января 2023 - Работа на UI страниц регистрации, авторизации и добавления нового автомобиля.
  • 12 января 2023 - Добавление errors handling на клиентской части при добавлении нового автомобиля.
  • 13 января 2023 - Ревакторинг html-страниц и некоторых endpoints.
  • 14 января 2023 - Переход к более новой версии Bootstrap 5+ и переделывание логики страниц регистрации и авторизации.
  • 15 января 2023 - Работа со страницей добавления нового автомобиля и исправление части с валидацией.
  • 16 января 2023 - Работа с GoogleMaps Api и исправление ошибок.
  • 17 января 2023 - Рефакторинг, работа с Appsettings.json файлом. Настройка и первое взаимодействие с Duende Identity Server.
  • 18 января 2023 - Настроил правила работы Identity Server и очистка проекта от ненужных файлов.
  • 20 января 2023 - Привязка Duende Identity Server к Web Application (клиентской части).
  • 21 января 2023 - Переход обратно с Duende Identity Server к использованию кастомной JWT-Authorization и создание страницы Dashboard (личный кабинет пользователя).
  • 22 января 2023 - Попытка настрить Duende Identity Server для работы с MongoDB Entities.
  • 23 января 2023 - Рефакторинг. Удаление Duende Identity Server. Настройка AzureAD как одного из способов авторизвции. Добавление новых сущностей в MSSQL Server.
  • 24 января 2023 - Чистка проекта от файлов, связанных с настройкой Identity Server.
  • 25 января 2023 - Настройка авторизации через JwtBearer. Настройка AzureAD. Подключение Azure Blob Storage как одного из механизмов для хранения изображений автомобилей.
  • 26 января 2023 - Настроил Pipeline между серверным приложением и обеими БД. Добавление ActionNotes Repository как один из сервисов в приложение.
  • 27 января 2023 - Добавлены новые возможности, связанные с отображением некоторых данных о клиентах на странице Dashboard. Обновлена структура БД, где был добавлен новый столбец. Настроен Pipeline при получении данных для представления информации об учетной записи клиента.
  • 29 января 2023 - Работа над страницей Dashboard.
  • 31 января 2023 - Настройка действий, связанных с транспортными средствами на странице Dashboard. Добавлены функции ajax для загрузки страницы без обновления. Добавлена функция поиска по критериям.
  • 1 февраля 2023 - Настройа pipeline для отображения данных об автомобилях в каталоге.
  • 3 февраля 2023 - Работа с каталогом и действиями с этой страницы.
  • 5 февраля 2023 - Добавление на страницу с каталогом формы для улучшенного поиска среди доступных автомобилей из каталога.
  • 6 февраля 2023 - Настройка программной части при использовании поиска по критериям со страницы с каталогом.
  • 7 февраля 2023 - Добавление новой страницы для поиска ближайших автомобилей и работа с GoogleMaps Api.
  • 8 февраля 2023 - Закончил делать страницу для поиска ближайших автомобилей.
  • 9 февраля 2023 - Добавление страницы с отображением информациеи об автомобиле. Добавление интеграции с платёжным сервисом Stripe.
  • 10 февраля 2023 - Работа над программными методами при работе со страницей VehicleInformation.
  • 12-14 февраля 2023 - Работа с Azure VM. Настройка сервиса логгирования исключений Seq и его хостинг на AzureVM. Настройка доступа задеплоенного приложения к своей БД MSSQL.
  • 15 февраля 2023 - Работа над GitHub Actions и автоматическим Publish при Merge с Main branch.
  • 17 февраля 2023 - Работа над переводом сайта с Http на Https и добавление новых функций.
  • 19 февраля 2023 - Добавление новых моделей Rental и Payment и настрока Azure VM.
  • 21 февраля 2023 - Работа над отдельным сервисом для взаимодействия со Stripe Payment Service на стороне сервера.
  • 22 февраля 2023 - Работа над устранением ошибок, связанных со Stripe. Работа над созданием Stripe Checkout Sessions.
  • 24 февраля 2023 - Работа над процессом оплаты и его обработкой.
  • 26 февраля 2023 - Настройка принципа работы с заказами на пользованием автомобиля.
  • 27 февраля 2023 - Настройка серверных Requests и Responses при манипуляции с заказами на клиенте.
  • 28 февраля 2023 - Настройка принципа отслеживания просроченных заказов, также как Runtime обработки и получения формы при изменении статуса заказа.
  • 1 марта 2023 - Исправление ошибок с DateTime, запросами в БД и работа над функциональными возможностями приложения.
  • 3 марта 2023 - Работа над системой загрузки файлов-изображений и наложение ограничений на загружаемые файлы.
  • 4 марта 2023 - Добавление popups для отображения ошибок валидации на сайте.
  • 5 марта 2023 - Придание сайту адаптивности, исправление ошибок валидации и добавление страниц с кодом ошибки в случае появления.
  • 6 марта 2023 - Работа над Routing-ом и настройка отображения страниц с информацией об ошибках.
  • 7 марта 2023 - Настройка атрибутов в контроллерах клиентской и серверной части.
  • 8 марта 2023 - Настройка логгирования должным образом и добавление .tagets файла для решения проблемы версионности одинаковых пакетов в разных проектов.
  • 9 марта 2023 - Работа над удалением ненужных файлов, удалением ненужных зависимостей, а также небольшие правки в коде для улучшения оптимизации проекта.
  • 10 марта 2023 - Работа над Endpoints для редактирования данных об автомобиле.
  • 11 марта 2023 - Работа над контроллером клиента для добавления нового автомобиля.
  • 12 марта 2023 - Окончательная настройка pipeline между всеми контроллерами клиента и сервера после добавления атрибутов к параметрам контроллеров.
  • 13 марта 2023 - Работа над анализатором server response на клиентской стороне и настройка универсального обработчика этих responses.
  • 15 марта 2023 - Перевод всего сайта с DateTime.Now (локального времени) на объект DateTime.UtcNow (UTC времени).
  • 16 марта 2023 - Настройка Routing на серверной части в стиле REST.
  • 17 марта 2023 - Работа над страницей изменения данных уже существующего пользователя.
  • 19 марта 2023 - Работа над pipeline для редактирования информации.
  • 20 марта 2023 - Доработка страницы изменения данных уже существующего пользователя (Также работа над меню с изменением изображения пользователя и пароля).
  • 21 марта 2023 - Финальная настройка проекта и подготовка к финальной защите (ЗАВЕРШЕНИЕ ПРОЕКТА).

О том, что представляет из себя этот проект

Этот проект представляет из себя полноценное Web-приложение, работающее на одном уровне с PublicAPI, написанным в стиле Clean Architecture, позволяющее любому человеку, имеющему валидную карту для оплаты аренды и водительское удостоверение получить возможность арендовать на время машину другого пользователя, который также зарегистрировался, но не с целью аренды чужого автомобиля, а с целью предоставления своих автомобилей для пользования другим пользователям. Таким образом, выгоду могут получить как и разработчики приложения, получая процент с осуществляемых пользователями сделок, так и непосредственно сами пользователи, арендующие либо предоставляющие в аренду свои автомобили.

Что было реализовано за время работы над проектом

  • Главная страница с информацией о сервисе
  • Каталог с информацией о доступных автомобилях
  • Страница для поиска ближайших автомобилей
  • Страница регистрации нового пользователя
  • Страница авторизации
  • Страница добавления своего личного автомобиля авторизованным пользователем
  • Страница для отслеживания активности (личный кабинет)
  • Страница просмотра информации о выбранном автомобиле
  • Popup для выбора промежутка времени для аренды автомобиля
  • Страница с оплатой (интеграция со Stripe)
  • Страница с изменением информации уже добавленного автомобиля
  • Страница с изменением информации авторизованного пользователя
  • Popup для изменения изображения авторизованного пользователя
  • Popup для изменения пароля авторизованного пользователя

Какие сервисы, и вспомогательные библиотеки хочется отметить

  • Всплывающие уведомления (SweetAlert2)
  • Отображение автомобилей на карте (Google Maps API)
  • Оплата аренды автомобилей (Stripe)
  • Errors handling (ErrorOr NuGet Package)
  • Авторизация (JWT Bearer NuGet Package)
  • Получение секретных значений (Azure Key Vault)
  • Получение и работа с изображениями (Azure Blob Storage)
  • Продвинутая авторизация (Azure AD)
  • Логгирование (Seq Service)
  • Политика request-response pipeline (Polly)
  • Получение сертификатов HTTPs (Lets Encrypt Service)
  • Статический анализатор кода (PVS Studio)
  • Базы данных (MSSQL и MongoDB)
  • Автоматический push (GitHub Actions и Action Runners)
  • Хостинг (Azure VM)

и другие...

Общая информация о проекте, его функциональность и принцип работы

Весь проект был написан с нуля, с использованием bootstrap 5+ для оформления визуальной составляющей, а также с использованием функциональных возможностей Razor Pages, ну и C# .NET Core для написания backend составляющей. В качестве модели взаимодействия мной был сделан выбор в сторону MVC. На выходе мы имеем дело с Client-Server MVC Wep App.

Главная страница

13

Как только неавторизованный пользователь запускает приложение, он сразу же видит главный экран с информацией о сервисе. На данной странице находится вся необходимая информация для ознакомления нового пользователя со всеми возможностями сервиса. Сверху можно видеть элемент navbar, который всё время находится на любой из страниц и не пропадает из поля видения, предназначенный для осуществления навигации пользователя по страницам приложения. Navbar предоставляет следующие возможности:

  1. Перейти на главную страницу с информацией о сервисе
  2. Перейти в каталог с доступными автомобилями
  3. Перейти на страницу поиска ближайших автомобилей
  4. Перейти на страницу регистрации (для неавторизованного пользователя)
  5. Перейти на страницу авторизации (для неавторизованного пользователя)
  6. Выйти из аккаунта (для авторизованного пользоавтеля)
  7. Перейти в личный кабинет (для авторизованного пользоавтеля)
  8. Перейти на страницу с созданием объявления своего собственного автомобиля (для авторизованного пользователя)
  9. Выйти из аккаунта (для авторизованного пользователя)

14

Также, на странице присутствует карта от google, которая показывает расположение всех доступных, не арендованных автомобилей из каталога (на карте появляются маркеры, по котороым можно отследить текущее местоположение транспортных средств. При наведени на маркер появится изображение транспортного средства с его названием). В качестве ограничения, я выбрал город Минск, то есть карта расположена таким образом, чтоб охватить всю область города. Если автомобиль, скажем, будет находиться где-то на улицах Бреста, то на карте мы его не увидим (либо же нужно будет менять масштаб карты). В качестве доступных локаций для размещения автомобилей, я решил ограничиться Беларусью, то есть автомобиль, размещаемый авторизованным пользователем, должен находиться на территории РБ. Однако, ничего не мешает пользователю создать заказ на автомобиль в другом городе или даже стране.

Касательно самой карты, она была подключена в приложение при помощи специального ключа, который работает без каких либо ограничений для поиска местоположения по известным Latitude и Longitude.

15

Независимо от страницы, в самом низу, будет расположена информация о разработчиках приложения и ссылки на соответствующие соц. сети и ресурсы Sam Solutions.

Страница с каталогом и её составляющие

16

На странице с каталогом пользователям будет предоставлена возможность просмотреть всю доступную краткую информацию об автомобилях, а также осуществлять поиск по критериям среди автомобилей, приведенных в каталоге. На странице есть возможность:

  • Осуществить поиск по 3-ём гланым критериям: Названию, краткому описанию и цене
  • Точечный поиск авто по криетриям (смотри рисунок ниже)
  • Счётчик отображаемых и доступных автомобилей в левом нижнем углу экрана
  • Саморасширяющийся Navbar для перемещения по каталогу в правом нижнем углу экрана

1

Касательно информации об автомобилях, в каталоге представлены:

  • Наименования автомобилей
  • Их краткое описание
  • Цеза за час и день пользования
  • Время с прошлого оформления заказа на этот автомобиль
  • На информацинной карточке присутствует кнопка, при нажатии на которую авторизованный пользователь будет перенаправлен на страницу с более детальной информацией о выбранном транспортном средстве, с которой также сможет оформить заказ на пользование (IMPORTANT Только авторизованный пользователь может получить доступ к просмотру более детальной информации об автомобиле)

17

На странице также присутствует возможность вызвать форму, необходимую для осуществления точечного поиска транспортных средств. Тут пользователю предоставляется множество разных фильтров, с помощью которых он может найти интересующие его автомобили в каталоге.

Таким образом, каталог позволяет рассмотреть ассортимент представленных транспортных средств и выбрать какой-либо экземпляр на свой вкус и цвет.

Как только пользователь нажимает кнопку Log In, он немедленно перенаправляется на страницу авторизации.

Страница авторизации и её составляющие

18

На странице авторизации, неавторизованному пользователю потребуется ввести свой Email (или Login) и Password для успешной авторизации. При ошибке в заполнении поля - будет отображаться сообщение об ошибке при заполнении:

19

Если все поля заполнены правильно, но авторизация не прошла - пользователю будет представлено сообщение о неудачной авторизации:

20

При успешной авторизации, уже авторизованный пользователь, будет перенаправлен на страницу Dashboard (личный кабинет), на которой появится сообщение об успешной авторизации, которое автоматически пропадает через 3 секунды после своего появления.

21

Если же у пользователя нет своего аккаунта, пользователю необходимо создать свой аккаунт, переход на страницу для осуществления чего осуществляется через нажатие кнопки Sign Up справа элемента Navbar.

Страница регистрации и её составляющие

22

23

На странице с регистрацией нового пользователя, необходимо будет ввести ряд данных, чтобы программа внесла клиента в базу и регистрация была пройдена успешно. Вся страница наполнена валидацией, и, если что-то не пройдёт - пользователь будет уведомлён о том, в каком поле произошла ошибка (такой же приинцип, как и со сраницей авторизации). После успешной регистрации, пользователь будет перенаправлен на страницу с регистрацией, на которой появится сообщение об успешной регистрации.

Как только пользователь успешно войдёт в свой только что созданный аккаунт, он получит возможность не только просматривать более детальную информацию об автомобилях в каталоге, но и добавлять свои собственные автомобили, а также отслеживать статистику по своим действиям и действиям другими пользователями с его автомобилями.

Страница для публикации своего личного автомобиля

24

25

На данной странице пользователь должен будет предоставить соответствующую информацию о своём автомобиле, а также установить тариф, по которому будет производиться аренда автомобиля. На странице также присутствует валидация (аналогично странице авторизации и регистрации). Как только пользователь успешно поделится своей машиной, она сразу же появится в его аккаунте, однако для её публикации, администратор должен одобрить заявку, после чего пользователь сможет опубликовать автомобиль через свой личный кабинет, а также редактировать информацию и всячески взаимодействовать с этим автомобилем. (Так как пользователь добавил свой автомобиль, логично, что показывать его в каталоге этому же пользователю будет не совсем логично и правильно. Однако, они всё же показываются в каталоге, НО, перейдя на страницу с информацией об этом автомобиле, владелец не сможет арендовать его, однако сможет ознакомиться с его описанием и представлением для других пользователей).

Страница Dashboard и её составляющие

res1.mp4

На странице Dashboard авторизованному пользователю предлагается просомтреть статистику своего аккаунта. На данной странице пользователь может просмотреть такую информацию, как:

  1. Данные об аккаунте + изображение профиля в самом верху страницы
  2. Привествующее пользователя сообщение слева, после секции с данными аккаунта
  3. Краткая информация о действиях пользователя, справа от приветствующего сообщения
  4. Статистические данные в виде полосок, отображающие статистику аккаунта в процентах, справа от секции с информацией о действиях пользователя
  5. Карткие секции со сводкой аккаунта, после 3-х верхних секций
  6. Информация об автомобилях текущего пользователя
  7. Информация о заказах текущего пользователя

Со страницы Dashboard, пользователь имеет возможность попасть на страницы с редактированием информации об автомобиле, либо же на страницу с редактированием информации аккаунта.

Страница с изменением данных пользователя и её составляющие

2

Головная страница позволяет пользователю изменить некоторые поля, связанные с его аккаунтом (такие, как Имя, Фамилия, Никнейм, Почта и др.)

Головное меню имеет несколько кнопок слева, после нажатия 2-ух из которых появляются мини-окна, которые также служат для изменения некоторой информации аккаунта.

Всплывающее окно с возможностью изменения изображения пользователя

3

При нажатии на соответствующую кнопку на головной странице, пользователю предлагается выбрать один из аватаров, который будет представлять его профиль. Как только пользователь выберет один из аватаров, после чего нажмёт на кнопку Apply и Save changes, аватар будет обновлён и пользователь сможет наблюдать другое изображение в своём аккануте.

Всплывающее окно с возможностью изменения пароля от аккаунта

4

При нажатии следующей по счёту кнопки, пользователю представится возможность ввести новый пароль от своего аккаунта, после чего пароль от его учётной записи будет полностью обновлён и старый пароль будет недействительным при повторном входе в аккаунт.

Страница с изменением данных автомобиля и её составляющие

5

После того, как пользователь добавит в аккаунт новый автомобиль и он будет успешно подтверждён администратором, пользователь сможет опубликовать свой автомобиль (он станет дотупным для аренды другим пользователям), либо спрятать его. Если автомобиль спрятан, при нажатии на соответствующее меню, пользователь сможет нажать на соответствующую кнопку Modify, после чего перейти на страницу с редактированием информации об автомобиле.

На данной странице он сможет изменить общую информацию об автомобиле (однако не сможет изменить изображение автомобиля и его категории с той целью, что если у него была бы такая возможность, после подтверждения автомобиля администратором, он бы мог загрузить в это объявление авсолютно любое изображение, абсолютно любую информацию, после чего другие пользователи видели бы у себя в каталоге неправильную и невалидную информацию).

TODO: Change everything that goes below.

Страница с информацией об автомобиле и её составляющие

8

Как только авторизованный пользователь нажимает кнопку Information на карточке транспортного средства из каталога, у него открывается соответствующая страница с выбранным автомобилем и более детальной информацией о экземпляре. С этой страницы, вскоре, можно будет оформлять заказы, которые будут фиксироваться в личном кабинете пользователя.

Личный кабинет пользователя и её составляющие

Мной была добавлена кнопка перехода в личный кабинет пользователя после авторизации, которая позволяет пользователю отслеживать свои заказы и добавленные им автомобили (Пока что активны только кнопки Publish и Hide для взаимодействия с автомобилями).

1 2

На данной странице, пользователь сможет не только просматривать и изменять информацию своего акканута, но и управлять своими автомобилями и своими заказами. После данных пользователя, можно увидеть следующие счётчики:

  • Vehicles added - Сколько автомобилей было добавлено пользователем (Фактически, количество автомобилей в личном кабинете)
  • Active vehicles - Сколько автомобилей опубликовано и доступно для аренды другими пользователями
  • Active orders - Сколько заказов закреплено за пользователем (Фактически, количество активных заказов аренды автомобиля)
  • Vehicle ordered - Сколько пользователь арендовал автомобилей за время существования аккаунта
  • Vehicles shared - Сколько заказов автомобилей пользователя было произведено за время существования аккаунта

Также, на этой странице можно просматривать такую информацию, как:

  1. Активные заказы
    • Id заказа
    • Название арендованного автомобиля
    • Оплаченное время
    • Оставшееся время
    • Время окончания заказа
  2. Добавленные автомобили
    • Id автомобиля
    • Название автомобиля
    • Цена автомобиля в формате (час - день)
    • Дата добавления
    • Количество раз, которое автомобиль был арендован другими пользователями
    • Статус автомобиля

При работе с таблицей автомобилей, можно наблюдать 3 цвета:

  • Жёлтый - Автомобиль добавлен, но не отображается в каталоге
  • Белый - Автомобиль добавлен в каталог и ожидает своего арендатора
  • Зелётный - Автомобиль был арендован другим пользователем

В зависимости от состояния и цвета автомобиля, пользователю открываются/блокируются новые/старые функции

Страница с редактированием информации активного пользователя

Как было сказано выше, для авторизованного в систему пользователя появляется возможность заходить в свой личный кабинет и отслеживать всю информацию, связанную с его заказами, а также автомобилями, которые данный пользователь предоставил для пользования другим пользователям нашего сервиса. Но что, если какая-то информация была введена не совсем корректно, если данные пользователя поменялись... А может быть опубликовавший автомобиль пользователь решит каким-то образом выделться на фоне других??? Для решения этих задач мной были разработаны страницы с редактированием информации как о текущем пользователе, так и о его автомобилях:

Из своего личного кабинета, перейти на страницу с редактированием информации о себе, пользователь может при помощи нажатия на соответствующую кнопку Edit Profile

1

При нажатии, пользователю открывается страница, на которой он может менять любую информацию, что отображена на странице

2

В частности: аватар своего профиля (на выбор 7 изображений из предложенных (1 default-ная, которая присваивается каждому новому пользователю, и 6 других на выбор))

3

Также можно поменять свой пароль. Установление нового пароля я сделал таким образом, что вводить предыдущий не понадобится (в реальности же, необходимо было бы запрашивать реальный пароль перед тем, как устанавливать новый)

4

Из простого, пользователь может менять любое из полей на данной странице (например, описание профиля, свой номер телефона, e-mail и тд). После того, как все интересующие пользователя поля были изменены, необходимо нажать на соответствующую кнопку Save Changes (новый пароль устанавливается автоматически при нажатии кнопки Save на странице с установлением нового пароля). Если была произведена какая-то ошибка при заполнении полей, пользователь может нажать на кнопку Cancel Chnages, что вернёт страницу в её первоначальный вид (тобиш к старым данным), либо же нажать на кнопку Get Back, которая перенесёт его обратно в свой личный кабинет.

Страница с редактированием информации автомобиля активного пользователя

Собственно, касаемо автомобилей, пользователь также может менять ту или иную информацию, преведенную на странице:

5

Однако, количество доступных полей для изменения в несколько раз меньше, чем у пользователя. Почему так? Дело в том, что при разработке, мне в голову пришла мысль: У каждого автомобиля ведь отслеживается число заказов. А что, если пользователь мог бы менять автомобиль полностью, скажем, поменять его изображение и название? Рейтинг у этого автомобиля остался бы тот же, а вот детальное описание полностью бы изменилось. Как по мне, такой подход смог бы играть ключевую роль в определении другими пользователями, какой автомобиль ему выбрать: например, пользователь, разместивший свой автомобиль год назад, явно проигрывал бы пользователю, который поменял бы описание своего старого автомобиля на описание более нового. Таким образом, мной был сделан вывод, что информацию нужно скрыть от редактирования, а доступными оставить только самые необходимые поля: поля с тарифом, описанием, а также местоположением.

Страница с оформлением нового заказа на аренду автомобиля

Дюбой из авторизованных пользователей может просматривать детальную информацию об автомобилях других пользователей в каталоге. Со страницы каждого автомобиля, пользователь может перейти на страницу с оформлением заказа на пользование этим автомобилем:

6

На этой странице ему предлагается выбрать временной промежуток, в который он сможет пользоваться автомобилем.

7

Выбор промежутка времени осуществляется с помощью элемента daterangepicker, в котором мной было установлено: Время начала - округление в сторону ближайшего часа. Время конца (default-ное) - время начала + 1 час. Таким образом, минимальное время для использования авто - 1 час. Макисмальное же время, которое я поставил - 7 дней со времени начала. Подсчёт суммы к оплате же происходит по формуле: Число дней умноженное на тариф/день + число часов * тариф/час. Как только пользователь сделает все необходимые приготовления и подтвердит заказ - он будет перенаправлен на страницу с оплатой:

8

На странице с оплатой приведена вся информация, необходимая пользователю для того, чтоб ещё раз перепроверить свой заказ. Как только оплата будет произведена, пользователи смогут найти автомобили в их личном кабинете: Пользователь, который владеет автомобилем - увидит, что автомобиль был арендован, а пользователь, что арендовал автомобиль - увидит полную информацию об оплаченном времени а также всю информацию касательно оставшегося времени и времени окончания аренды на этот автомобиль. Выглядит это следующим образом:

1

Когда пользователь решит завершить свой заказ досрочно (заказ завершается не системой, отвечаемой за просроченные заказы, а самим пользователм, совершившим заказ), у него появляется возможность выставить рейтинг для автомобиля, которым он пользовался на протяжении N-го промежутка времени:

2

Опять же, у пользователя есть выбор: Поставить рейтинг автомобилю, после чего нажать на соответствующую кнопку Submit and Finish и завершить заказ вместе с рейтингом, либо же пропустить шаг с выставлением рейтинга, нажав на кнопку Finish and not submit, и завершить заказ без отправки рейтинга.

Сам же рейтинг можно увидеть на странице с информацией об автомобиле. В зависимости от поставленыых пользователями оценок, на странице будет отображаться общая статистика. Автомобиль с 0 звёздами можно было увидеть выше, а страница с автомобилем с проставленным рейтингом от одного пользователя показана ниже:

3

Техническая документация

В данном разделе я постараюсь описать, а как проект устроен изнутри, что происходит внутри <Чёрного ящика>. Это поможет лучше разобраться в проекте тем, кто хоть немного имеет представление о языке программирования C# и аспекты программирования на нём.

  1. Хранилище автомобилей

Конечно, для того, чтобы работать с какими-либо данными, для начала, нужно определиться, а как именно их хранить? Конечно, супер крупные проекты используют для хранения такие БД, как Oracle, PostgreSQL, MySQL, MSSQL и другие. Однако, проблема такого подхода состоит в том, что доступ к приложениям, привязанным к базам данных, можно получить только в том случае, если подключение к той самой базе данных может быть получено на устройстве пользователя (За такую функцию приходится платить крупные суммы денег компаниям-гигантам). Так как я не располагаю большими суммами денег, для возможности любому пользователю запускать проект и не испытывать проблемы с его тестированием и пользованием, мной была выдвинута идея использования сериализации и десериализации в контекстах относительных путей. Таким образом, проблем с получением доступа у пользователей, скачавших приложение из репозитория, возникнуть не должно.

Каким же образом происходит получение данных из JSON-файлов и как вообще устроено получение данных? (Для всех локальных хранилищ)

Для того, чтобы не привязываться к какому-то определённому типу хранилищ, мной был применён подход Dependency Injection, а именно внедрение Singleton зависимостей между хранилищами и локальным репозиторием программы. То есть: в моей программе есть интерфейс:

    public interface IVehiclesRepository

Этот интерфейс будет являться связующим звеном для получения данных. В данном интерфейсе есть набор методов, которые должны быть реализованы для того или иного сервиса, чтоб им можно было пользоваться независимо от реализации методов. Главное, чтоб эти методы были реализованы в том классе, который решит реализовать этот интерфейс. Для реализации локального интерфейса, так как я исользую локальное хранилище данных в файлах, а не в БД, я решил использовать Singleton подход, что будет означать, что объект сервиса будет создаваться только при первом обрпщении к нему, после чего все последующие запросы будут проходить через тот самый сервис. Ниже, мы явно указываем, что если кто-то захочет получить объект этого сервиса через интерфейс, мы дадим ему конкретную реализацию (В данном случае реализацию локального репозитория):

builder.Services.AddSingleton<IVehiclesRepository, VehiclesLocalRepository>(); // Где требуется IVehiclesRepository - дай реализацию VehiclesLocalRepository

Сами же локальные репозитории реализованы таким образом, чтоб уменьшить количество загрузок из файлов в само приложение. Как только происходит первое обращение к сервису - производится работа метода SetUpLocalRepository. Этот метод запишет в путой объект List<> модели, считанные из JSON - файла, после чего все манипуляции будут проходить непосредственно через сам этот List<>, а если данные будут меняться - будет вызываться асинхронный метод SaveChanges(), который призван асинхронно записать изменения в файл (Повторное считывание файла не происходит, так как мы работаем с объектом List<>, который мы также изменили перед тем, как запрашивать обновление JSON-файла). Таким образом, применённый мной подход не только позволит пользователю получать доступ в кратчайшие сроки, но и позволит избежать излишних нагрузок системы для загрузки данных из файлов каждый раз при обращении к сервису.

  1. От чего вообще зависит то, какие автомобили видит пользователь как на главной странице(в виде маркеров), так и на странице каталога?

При проектировнии, мной была выявлена следующая проблема - А должен ли пользователь, добавивший автомобиль в каталог, иметь возможность взаимодействовать с тем же самым автомобилем из каталога? Конечно же нет. Такой подход позволит пользователю, добавившему автомобиль в каталог, арендовать свой же автомобиль (В чём смысл???). Для избежания этой проблемы, мной был выбран следующий подход:

Представим, что на данный момент, нет ни пользователей, ни добавленных автомобилей. Вот мы запускаем наше приложение. На главной странице мы видим карту с 0 маркерами, а в каталоге также 0 автомобилей. Мы создаём новый аккаунт, входим в него, делимся своим автомобилем. НО! Автомобиль не появляется в каталоге. В чём же проблема? Дело в том, что перед тем, как отобразить автомобиль в каталоге, добавивший его пользователь должен явно опубликовать автомобиль из своего личного кабинета путём нажатия кнопки Publish напротив выбранного автомобиля. Как только он произведёт публикацию, для этого пользователя в каталоге ничего не изменится, он также будет видеть 0 автомобилей. ОДНАКО! Если мы выйдем из аккаунта или создадим новый - В каталоге будет виднеться тот самый автомобиль, которым поделился и который опубликовал предыдущий пользователь. Таким образом, пользователь, добавивший автомобиль и разместивший его в каталог, не может увидеть свои же собственные автомобили (Все свои добавленные автомобили пользователь может увидеть в своём личном кабинете). ЗАТО! После того, как пользователь поделится своим автомобилем и разместит его в каталог из личного кабинета, хотя он не видит этот автомобиль в каталоге, он может перейти на главную страницу и обратить внимание, что его автомобиль появился на карте в виде маркера (Однако в каталоге его по-прежнему нет). Дело в том, что система показывает ЛЮБОМУ пользователю ВСЕ автомобили на карте в виде маркера, которые были ОПУБЛИКОВАНЫ в личном кабинете не зависимо от того, какой пользователь сейчас находится в системе. Однако в каталоге, система показывает те же самые автомобили, что изображены на карте на главной странице в виде маркеров, НО ещё проверяется условие, что ID владельца автомобиля не равно ID текущего пользователя, вошедшего в аккаунт. Для неавторизованного пользователя ID не проверяется. Ему показываются те же самые автомобили в каталоге, что и на карте на главной странице.

Таким образом, подводя итог:

  • Автомобиль появится на карте и в каталоге только в том случае, если пользователь, поделившись автомобилем, опубликует его из своего личного кабинета путём нажатия кнопки Publish (И пропадёт, если он решит убрать его из каталога путём нажатия кнопки Hide)
  • Неавторизованному пользователю (на карте и в каталоге) видны только те автомобили, которые были опубликованы пользователями из личного кабинета
  • Авторизованному пользователю (на карте) видны только те автомобили, которые были опубликованы пользователями из личного кабинета
  • Авторизованному пользователю (в каталоге) видны только те автомобили, которые были опубликованы пользователями из личного кабинета и которые не относятся к текущему пользоватлю
  1. Добавление своего автомобиля авторизованным пользователем

При добавлении автомобиля, на странице использованы такие технологии, как локальное хранилище данных (Local Storage) для хранения координат местоположения автомобиля, а также специальные скрипты и элемент C# IFormFile для получения файла изображения со сраницы.

Local Storage

Предположим, что мы - очень невнимательные пользователи, которые всё время допускают ошибки на страницах. Для того, чтобы избежать повторного ввода координат каждый раз при обновлении страницы, пной было принято решение хранить координаты GoogleMaps в локальном хранилище и чистить эти данные в случае покидания пользователем страницы добавления своего автомобиля. Так как данные, применяемые при работе с GoogleMaps являются специфическими (представление типа данных float отличаются знаком разделителя) чтоб избежать большого количества манипуляции с данными, используется локальное хранилище, которое призвано сократить число операция приведения данных из одного представления в другое.

IFormFile и скрипты

При работе с изображеним, мы не можем получать доступ к файловой системе пользователя со страницы Razor, так как это просто недопустимо в рамках работы системы безопасности, поэтому приходится использовать определённые подходы, например, как работа с IFormFile. Объекты этого типа хранят всю необходимую информацию о выбранном изображении, которое выберет пользователь, при этом не представляет никакой угрозы для файловой системы компьютера в целом. Однако использование такого подхода имеет недотаток - пользователю необходимо каждый раз выбирать изображение снова и снова, если пользователем повторно допускаются ошибки на странице добавления автомобиля.

Технические аспекты проекта (проблемы и их решения)

Ниже я постарался описать интересные технические моменты, которые я предпринимал в течение проектирования и разработки проекта.

Проблемы, с которыми столкнулся во время разработки и какой план действий принмал

Работа со страницей для отображения каталога и изменения параметров отображения (фильтры, кол-во автомобилей на странице и тд.)

При работе с получением автомобилей из репозитория у меня было 2 идеи, как решить данную задачу: Либо при каждом обращении к контроллеру формировать новый объект с информацией о машинах и передавать его во View, либо же принимать этот объект из View, если он уже был передан однажды, при этом не делая никаких дополнительных запросов в репозиторий, и модифицировать согласно предпочтениям пользователя по количеству отображения автомобилей на странице и тд. Сначала я принял решение пойти через получение модели из View, однако столкнулся с такой проблемой, как Model Binding, которая просто так не даёт получить List переданных в качестве модели автомобилей: Либо нужно использовать Ajax, при этом заранее сериализовать модель в JSON и после чего десериализовать полученную JSON-строку в Controller-е, либо никак) Поэтому я выбрал первый путь (через создание объекта), так как в этом случае придётся манипулировать в основном со ссылками на данные, нежели чем с самими данными. (p.s. Также, работа через первый подход потребовала бы накладных расходов на проверку, а не добавилась ли в репозиторий новая машина, но уже другим пользователем, и если добавилась, также необходимо было бы добавить её в модельку, пришедшую из View)

Работа с заказами и общий принцип их оформления

Изначально, мной была заложена идея, что пользователь может как оформить заказ на определённое время, внеся предоплату, так и просросить его, за что потребуется внести дополнительные деньги за просроченное время. Однако, при дальнейшем развитии идеи, мной были выявлены следующие проблемы, касательно как программной, так и правовой идеи такого подхода:

  • Что, если пользователь возьмёт автомобиль в аренду, и больше не будет входить в аккаунт (скажем, год. Это приведёт к переполнению типа при отслеживании суммы оплаты дополнительного времени. В таком случае необходимо было бы ввести ограничение на просроченное время, но в таком случае, что делать с просроченным заказом, если пользователь не сможет оплатить его, и что делать с этим автомобилем??? Выставить мы его обрано в каталог также не можем, тк мы не уверены, что с ним и с заказом в итоге произошло)
  • Что, если пользователь просто забудет закончить заказ? Как это будет решаться в правовом поле?
  • Что, если пользователь просрочит, закончит, но не оплатит сумму за просроченное время? Как долго этот заказ будет висеть, как регулировать действия пользоватля при наличии хотя бы одного не оплаченного заказа??
  • И другие проблемы, которые появились при использовании этого подхода...

Поэтому, мной был выбран следующий план действий: Подразумевается, что заказ начинается, как только пользователь оформляет заказ на пользование авто и оплачивает его, а заканчивается этот же заказ ровно тогда, когда время пользования станет равно оплаченному времени. После чего, автомобиль сразу становится доступным для других пользователей в каталоге, а нынешний заказ пропадает с личного кабинета пользователя, оплатившего время на его использование. Если другой пользователь оформит заказ на тот же автомобиль и при прибытии на место обнаружит, что автомобиль отсутствует на том месте, на котором он расположен на карте, он имеет право подать в суд на человека, который просрочил своё время (собственно как и заказчик). Таким образом, каждый пользователь, который оформляет заказ, берёт на себя ответственность закончить его во время.