0% found this document useful (0 votes)
13 views63 pages

clc04 Tmhung Ass4

The document outlines the requirements for an e-commerce system, identifying three primary actors: Customers, Staff, and the System, each with specific functions and interactions. It details various use cases for each actor, including customer actions like account registration, product browsing, and payment processing, as well as staff functions such as order management and inventory updates. Additionally, the document emphasizes a microservices architecture using the Django framework for the proposed Online Course Platform.

Uploaded by

Minh Tran
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
13 views63 pages

clc04 Tmhung Ass4

The document outlines the requirements for an e-commerce system, identifying three primary actors: Customers, Staff, and the System, each with specific functions and interactions. It details various use cases for each actor, including customer actions like account registration, product browsing, and payment processing, as well as staff functions such as order management and inventory updates. Additionally, the document emphasizes a microservices architecture using the Django framework for the proposed Online Course Platform.

Uploaded by

Minh Tran
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 63

https://github.

com/finetglazer/Project-Django

CHAPTER 1: REQUIREMENTS OF E-COMMERCE

1.1 Determine Requirements for


E-Commerce System
1.1.1 Actors
In this e-commerce system, we have identified three primary actors who will interact with the
system in distinct ways, each with their own specific requirements, privileges, and
constraints:

1. Customer The Customer actor represents end-users who utilize the e-commerce platform
to browse and purchase products. These individuals are the primary revenue generators for
the business and require a seamless, intuitive user experience. Customers may be either
anonymous (not logged in) with limited functionality or authenticated users with full access to
personalized features. They interact primarily with the front-end interface of the application
and require no special technical knowledge to operate the system effectively.

2. Staff The Staff actor encompasses employees of the organization who manage the
operational aspects of the e-commerce platform. This includes inventory managers, product
catalog administrators, order processors, and customer service representatives. Staff
members require administrative access to backend functionalities that are not exposed to
regular customers. They perform critical business operations that ensure the smooth
functioning of the e-commerce ecosystem.

3. System The System actor represents automated processes and background services that
operate independently without direct human intervention. These include scheduled tasks,
notification services, inventory management systems, and integration points with external
services such as payment gateways and shipping providers. The System actor ensures that
critical business processes continue to function reliably without requiring constant human
supervision.

1.1.2 Functions with respect to actors


Customer Functions
Function Function Description Priorit
ID Name y

CUST-00 Register Allows new users to create an account by providing High


1 Account username, email, and password. The system
validates input data and creates a new user account
in the database.

CUST-00 Login Authenticates existing users through username and High


2 password verification, establishing a secure session
for the user to access personalized features.

CUST-00 Browse Enables users to view available products, potentially High


3 Products categorized by type, popularity, or other classification
schemes.

CUST-00 Search Permits users to find specific products by entering High


4 Products keywords that match product names, descriptions, or
categories.

CUST-00 View Displays comprehensive information about selected High


5 Product products, including images, descriptions, pricing, and
Details availability.

CUST-00 Add to Cart Allows users to select products for potential purchase High
6 by adding them to a virtual shopping cart.

CUST-00 View Cart Displays all products currently in the user's cart, High
7 including quantities and calculated total prices.

CUST-00 Remove Enables users to remove unwanted items from their Mediu
8 from Cart shopping cart before proceeding to checkout. m

CUST-00 Checkout Facilitates the process of finalizing purchases, High


9 including address confirmation and payment method
selection.

CUST-01 Make Securely processes financial transactions through High


0 Payment integration with payment service providers.

CUST-01 View Order Allows users to review their past purchases, including Mediu
1 History order statuses and delivery information. m

Staff Functions
Function Function Description Priorit
ID Name y

STAFF-0 Login Provides secure authentication for staff members High


01 to access the administrative backend of the
system.

STAFF-0 Manage Enables staff to add, edit, or remove products from High
02 Products the catalog, including updating information such as
prices, descriptions, and images.
STAFF-0 Manage Allows staff to view, process, update the status of, High
03 Orders and potentially cancel customer orders.

STAFF-0 View Sales Provides access to analytical data regarding sales Mediu
04 Reports performance, popular products, and revenue m
metrics.

STAFF-0 Update Enables staff to adjust product stock levels High


05 Inventory manually when necessary, ensuring accurate
availability information for customers.

STAFF-0 Manage Allows staff to assist customers by viewing their Mediu


06 Customer account information, order history, and potentially m
Accounts making changes on their behalf.

STAFF-0 Configure Provides access to modify operational parameters Low


07 System of the e-commerce platform, such as shipping
Settings costs or promotional discounts.

System Functions
Function Function Name Description Priorit
ID y

SYS-001 Process Automatically handles the secure transaction of High


Payment funds between customer accounts and the
business through payment gateways.

SYS-002 Update Automatically adjusts product stock levels when High


Inventory purchases are made to maintain accurate
availability information.

SYS-003 Send Order Automatically generates and delivers email Mediu


Confirmation notifications to customers when orders are m
placed, processed, or shipped.

SYS-004 Monitor System Continuously checks system performance and Mediu


Health functionality, potentially alerting administrators to m
issues.

SYS-005 Generate Automatically compiles business intelligence data Low


Reports at scheduled intervals for management review.

SYS-006 Backup Data Periodically creates secure copies of critical High


system data to prevent loss in case of system
failure.

SYS-007 Process Manages the logistics and financial aspects of Mediu


Returns product returns and refunds. m
1.1.3 Use case Diagrams
For the e-commerce system, we have developed a comprehensive use case diagram that
illustrates the interactions between the identified actors and the system functions. The use
case diagram visually represents the system's functional requirements and depicts the
relationships between actors and use cases.

Customer Actor Use Cases Detailed Descriptions

Register Account This use case begins when a new customer decides to create an account
on the e-commerce platform. The customer navigates to the registration page and provides
required information including username, email address, and password. The system
validates this information to ensure it meets the required criteria (e.g., unique username,
valid email format, password strength). If validation is successful, the system creates a new
user account and stores the information securely in the database. The system may also
send a confirmation email to verify the user's email address before fully activating the
account. This use case is essential for establishing unique identity and personalized
experiences for customers.

Login The Login use case is initiated when a returning customer wishes to access their
account. The customer enters their username and password credentials on the login page.
The system verifies these credentials against the stored information in the database. If the
credentials match, the system creates an authenticated session for the user, granting them
access to personalized features such as their order history, saved addresses, and shopping
cart. If authentication fails, the system provides appropriate error messages and may offer
password recovery options. This use case is critical for maintaining security and providing
personalized service.

Browse Products This use case represents a fundamental shopping activity where
customers explore available merchandise. The customer accesses the product catalog
through various entry points such as the homepage, category pages, or recommendation
sections. The system retrieves and displays products in an organized manner, potentially
implementing pagination for large catalogs. Customers may filter or sort products based on
various attributes such as price range, category, brand, or customer ratings. This browsing
experience should be optimized for both desktop and mobile interfaces, with consideration
for loading times and visual presentation.

Search Products The Search Products use case enables customers to quickly locate
specific items of interest. It begins when a customer enters keywords into the search field.
The system processes this query against product names, descriptions, categories, and
potentially other metadata. The search functionality may incorporate advanced features such
as autocomplete suggestions, spelling correction, or semantic understanding of search
intent. Results are presented in order of relevance, with options for further refinement. This
use case is critical for enhancing customer satisfaction by reducing the time and effort
needed to find desired products.

View Product Details This use case occurs when a customer selects a specific product to
learn more about it. The system displays comprehensive information including
high-resolution images, detailed descriptions, specifications, pricing, availability, shipping
information, and customer reviews if available. Additional features might be present for
certain product categories, such as size charts for clothing or compatibility information for
electronics. The product detail page should also provide clear calls to action such as "Add to
Cart" and potentially related product recommendations. This use case is essential for
providing customers with sufficient information to make informed purchasing decisions.

Add to Cart The Add to Cart use case represents a critical conversion point in the customer
journey. When a customer decides to purchase a product, they activate the "Add to Cart"
function, which may include specifying quantity or product variations (e.g., size, color). The
system validates product availability, adds the item to the customer's shopping cart, and
typically provides visual feedback confirming the action. The system may also update the
cart indicator in the navigation area to reflect the current number of items. This use case
bridges browsing behavior and purchasing intent, making it a key metric for e-commerce
performance.

View Cart This use case is initiated when a customer wishes to review the items they've
selected for potential purchase. The system displays all products currently in the customer's
cart, including images, names, selected options, quantities, individual prices, and the
calculated subtotal. Customers can review this information before proceeding to checkout.
The cart interface typically provides options to adjust quantities, remove items, or continue
shopping. The system recalculates totals whenever changes are made. This use case
provides transparency in the purchasing process and a final opportunity for customers to
review their selections.

Remove from Cart The Remove from Cart use case allows customers to eliminate
unwanted items from their selection. When a customer decides they no longer wish to
purchase a particular item, they activate the removal function associated with that product in
their cart view. The system immediately removes the item, updates the cart contents, and
recalculates the total price. This functionality gives customers control over their purchase
decisions and helps prevent abandoned carts due to unwanted items that customers cannot
remove.

Checkout This complex use case represents the final stage of the purchasing process. It
begins when a customer decides to complete their purchase by initiating the checkout
process from their shopping cart. The system guides the customer through a structured flow
that includes confirming or entering shipping address, selecting a shipping method, choosing
a payment method, and reviewing order details before final confirmation. The system
calculates additional costs such as shipping fees and taxes, presenting a comprehensive
total. This use case may include validation at each step and typically involves integration
with other use cases such as Make Payment.

Make Payment The Make Payment use case handles the critical financial transaction
aspect of e-commerce. After a customer has reviewed their order and proceeds to payment,
the system securely collects payment information appropriate to the selected payment
method (credit card details, PayPal authorization, etc.). The system communicates with
external payment processing services to validate and process the payment. This use case
includes error handling for declined payments and security measures such as encryption of
sensitive financial data. Upon successful payment, the system updates the order status and
triggers subsequent processes such as inventory updates and order confirmations.

View Order History This use case provides customers with access to information about
their previous transactions. When a customer navigates to their order history section, the
system retrieves and displays a chronological list of past orders, including order dates, total
amounts, and current statuses. Customers can select individual orders to view more details
such as the specific products purchased, shipping information, and payment methods used.
This functionality enhances customer service by giving users self-service access to their
purchase information and potentially reducing support inquiries about order status.

Staff Actor Use Cases Detailed Descriptions

Login (Staff) The Staff Login use case is similar to customer login but provides access to
administrative functions. Staff members enter their credentials, which are authenticated
against staff accounts with appropriate permission levels. Upon successful authentication,
staff members are granted access to the administrative interface with functionality
appropriate to their role (e.g., inventory management, order processing). This use case
typically implements additional security measures such as stronger password requirements,
session timeouts, and potentially two-factor authentication for sensitive operations.

Manage Products This comprehensive use case encompasses all activities related to
maintaining the product catalog. Staff members can add new products by entering details
such as names, descriptions, pricing, categories, and uploading images. They can edit
existing product information to update prices, descriptions, or availability. They can also
temporarily or permanently remove products from the catalog when necessary. This use
case may include batch operations for efficient management of multiple products and
validation to ensure all required product information is provided.

Manage Orders The Manage Orders use case allows staff to oversee and process
customer transactions. Staff members can view all current orders with filtering options for
status, date range, or customer. They can update order statuses as orders progress through
fulfillment stages (processing, shipped, delivered, etc.). They can view detailed information
about specific orders including customer information, purchased products, payment status,
and shipping details. This use case may also include functionality to handle special
circumstances such as cancellations, modifications, or returns.

View Sales Reports This analytical use case provides staff with business intelligence
capabilities. Staff members can access predefined reports showing key metrics such as
revenue over time, bestselling products, sales by category, or geographic distribution of
customers. The system processes sales data to generate these reports with appropriate
visualizations such as charts and graphs. Staff may have options to customize date ranges
or other parameters and potentially export report data for further analysis in external tools.
This use case supports business decision-making by transforming raw transaction data into
meaningful insights.

Update Inventory The Update Inventory use case allows staff to maintain accurate stock
information. Staff members can manually adjust inventory levels for specific products,
potentially with batch operations for efficiency. This might be necessary due to physical
inventory counts, damaged goods, or receipt of new stock. The system records these
adjustments with appropriate timestamps and user identification for audit purposes. This use
case ensures that customers receive accurate availability information when browsing
products and helps prevent overselling of items that are out of stock.

System Actor Use Cases Detailed Descriptions

Process Payment This automated use case handles the secure processing of financial
transactions. When a customer submits payment information during checkout, the system
securely transmits this data to appropriate payment processing services (credit card
processors, PayPal, etc.). The system handles authentication and authorization of the
payment, processes the response from the payment service, and updates the order
accordingly. In case of failures or declines, the system manages appropriate error handling
and customer notifications. This use case operates without human intervention but includes
logging and exception handling for administrative oversight.

Update Inventory (Automated) Unlike the staff version, this automated use case adjusts
inventory levels in response to system events. When an order is successfully placed, the
system automatically reduces available stock for the purchased products. Similarly, when
orders are canceled or items returned, the system may increase available stock accordingly.
The system may also include threshold notifications to alert staff when products are running
low and need reordering. This automation ensures that inventory information remains
accurate without requiring constant staff intervention.

Send Order Confirmation This communication-focused use case manages customer


notifications about their orders. When an order is placed or its status changes, the system
automatically generates appropriate email or other notifications. Order confirmations typically
include order numbers, itemized lists of purchased products, pricing information, estimated
delivery dates, and potentially tracking information when available. These communications
follow predefined templates that maintain brand consistency while delivering necessary
information. This automated process ensures timely communication with customers
regarding their purchases without requiring staff to manually send updates.

Relationships Between Use Cases

Include Relationships:

●​ Checkout → Make Payment: The Checkout use case includes the Make Payment
use case because payment processing is an essential component of completing a
purchase.
●​ Checkout → Update Inventory: When a customer completes a purchase, the system
must update inventory levels to reflect the sold items.
●​ Register Account → Validate User Data: User registration inherently includes
validation of the provided information to ensure data integrity.

Extend Relationships:
●​ Browse Products → Add to Cart: The Add to Cart functionality extends the product
browsing experience when a customer decides to select a product for potential
purchase.
●​ View Cart → Remove from Cart: The ability to remove items extends the cart viewing
functionality when customers wish to modify their selections.
●​ View Product Details → Write Review: After viewing product details, customers may
optionally extend this interaction by writing reviews of products they've purchased.

This detailed use case diagram serves as a foundation for understanding the system's
requirements and guides the subsequent design and implementation phases of the
e-commerce project. It clearly defines the boundaries of the system and establishes the
expected interactions between users and the application, ensuring that development efforts
are aligned with business objectives and user needs.

**1.2 Analyze Requirements**

This section delves into the analysis of the requirements for our proposed Online Course
Platform. The primary architectural decision made at this stage is to adopt a microservices
approach, utilizing the Django framework for the implementation of individual services. This
approach is chosen to promote modularity, scalability, and independent development cycles
for different parts of the platform, even though for this assignment, we aim for conceptual
simplicity rather than complex implementation. The following subsections detail the
decomposition into services, the data models within those services, the functions handling
business logic, the user interface templates, and the communication mechanisms between
services.

**1.2.1 Decompose the system in microservices with Django**

To structure the Online Course Platform effectively, we will decompose the system into
distinct, manageable microservices. Each microservice will handle a specific domain of the
application's functionality. While microservices allow for technological diversity, for simplicity
and consistency in this project, we will assume each service is built using the Django
framework.

The decomposition results in the following primary microservices:

1. **User Service (`UserService`)**:


* **Responsibility**: This service is solely responsible for managing user accounts. Its
tasks include user registration, authentication (login/logout), profile management
(viewing/updating user details), and potentially handling user roles or permissions in a more
complex scenario.
* **Rationale**: Separating user management ensures that authentication and user data
are handled consistently and securely in one place. Other services needing user information
will interact with this service via its API. For instance, when a user enrolls in a course, the
`EnrollmentService` would need to verify the user's existence and potentially their identity
token by communicating with the `UserService`.

2. **Course Service (`CourseService`)**:


* **Responsibility**: This service manages the course catalog. It handles creating new
courses, updating existing course details (like title, description, instructor), retrieving lists of
available courses, and fetching details for a specific course. It essentially acts as the source
of truth for all information directly related to the courses themselves.
* **Rationale**: Course information is a distinct domain. Separating it allows the course
catalog to evolve independently. For example, adding features like course categories or
prerequisites would primarily impact this service. Other services, like `EnrollmentService`,
would query the `CourseService` to get details about courses users want to enroll in.

3. **Enrollment Service (`EnrollmentService`)**:


* **Responsibility**: This service manages the relationship between users and courses –
specifically, user enrollments. Its functions include enrolling a user in a course, unenrolling a
user, and listing the courses a specific user is enrolled in. It might also track progress or
completion status in a more advanced version.
* **Rationale**: Enrollment represents the interaction *between* users and courses.
Handling this logic separately keeps both the `UserService` and `CourseService` cleaner, as
they don't need to manage the complex state of who is enrolled in what. This service acts as
a crucial link, connecting users and courses based on their interactions.
**Technology Choice**: Each of these services (`UserService`, `CourseService`,
`EnrollmentService`) will be implemented as a separate Django project. This allows for
independent development, testing, deployment, and scaling, which are key benefits of the
microservice architecture, even if managed simply for this assignment.

**1.2.2 Classes with attributes of service models (models.py)**

Within each Django microservice, the `models.py` file defines the structure of the data that
the service manages. These models map directly to database tables, facilitated by Django's
Object-Relational Mapper (ORM).

1. **`UserService` Models**:
* `class User(models.Model):`
* `user_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)`:
Unique identifier for the user. Using UUID is good practice in distributed systems to avoid ID
collisions.
* `username = models.CharField(max_length=150, unique=True)`: The user's chosen
username for login. Must be unique.
* `email = models.EmailField(unique=True)`: The user's email address, also unique.
Used for communication and potentially password recovery.
* `password_hash = models.CharField(max_length=128)`: Stores the securely hashed
version of the user's password (Django handles the hashing).
* `date_joined = models.DateTimeField(auto_now_add=True)`: Timestamp for when the
user account was created.
* `is_active = models.BooleanField(default=True)`: Flag to indicate if the account is
active.

2. **`CourseService` Models**:
* `class Course(models.Model):`
* `course_id = models.UUIDField(primary_key=True, default=uuid.uuid4,
editable=False)`: Unique identifier for the course.
* `title = models.CharField(max_length=200)`: The title of the course.
* `description = models.TextField()`: A detailed description of the course content.
* `instructor_name = models.CharField(max_length=100)`: Name of the course
instructor (kept simple here; could be a link to a User in `UserService` via API call in a real
scenario).
* `creation_date = models.DateTimeField(auto_now_add=True)`: Timestamp for when
the course was added to the platform.
* `last_updated = models.DateTimeField(auto_now=True)`: Timestamp for the last
modification of the course details.

3. **`EnrollmentService` Models**:
* `class Enrollment(models.Model):`
* `enrollment_id = models.UUIDField(primary_key=True, default=uuid.uuid4,
editable=False)`: Unique identifier for the enrollment record.
* `user_id = models.UUIDField()`: Stores the `user_id` (from `UserService`) of the
enrolled user. Note: This is not a direct Django `ForeignKey` across services but stores the
ID obtained via API communication.
* `course_id = models.UUIDField()`: Stores the `course_id` (from `CourseService`) of
the course the user is enrolled in. Again, not a direct `ForeignKey`.
* `enrollment_date = models.DateTimeField(auto_now_add=True)`: Timestamp for
when the enrollment occurred.
* `status = models.CharField(max_length=50, default='active')`: Could represent
enrollment status (e.g., 'active', 'completed', 'cancelled').

These models define the core data entities managed by each service, providing a clear
structure for storing information within their respective databases.

**1.2.3 Determine functions in services (views.py)**

The `views.py` file in each Django service contains the logic to handle incoming HTTP
requests, interact with the service's models (and potentially other services via API calls), and
return HTTP responses. For simplicity, we can outline function-based views.

1. **`UserService` Views**:
* `register(request)`: Handles POST requests to create a new user account based on
provided username, email, and password. Interacts with the `User` model.
* `login(request)`: Handles POST requests to authenticate a user based on
username/password. If successful, might return an authentication token (e.g., JWT).
* `get_user_profile(request, user_id)`: Handles GET requests to retrieve the profile details
(username, email, date joined) for a specific `user_id`. Interacts with the `User` model.
* `update_user_profile(request, user_id)`: Handles PUT or PATCH requests to update
user details (e.g., email). Requires authentication.

2. **`CourseService` Views**:
* `list_courses(request)`: Handles GET requests to return a list of all available courses (or
a paginated list). Interacts with the `Course` model.
* `get_course_details(request, course_id)`: Handles GET requests to retrieve detailed
information for a specific `course_id`. Interacts with the `Course` model.
* `create_course(request)`: Handles POST requests (likely requiring admin privileges) to
add a new course to the catalog. Interacts with the `Course` model.
* `update_course(request, course_id)`: Handles PUT or PATCH requests (admin privilege)
to modify details of an existing course. Interacts with the `Course` model.

3. **`EnrollmentService` Views**:
* `enroll_in_course(request)`: Handles POST requests (requires authenticated user) to
create an `Enrollment` record linking a `user_id` (from token/session) and a `course_id`
(from request body). It would first potentially verify user existence with `UserService` and
course existence with `CourseService` via API calls. Interacts with the `Enrollment` model.
* `list_user_enrollments(request, user_id)`: Handles GET requests (requires authenticated
user, checking if the requestor matches `user_id` or is admin) to list all `course_id`s a
specific user is enrolled in. Interacts with the `Enrollment` model. It might then need to call
`CourseService` to get details for these `course_id`s to present meaningful data.
* `unenroll_from_course(request, enrollment_id)`: Handles DELETE requests (requires
authenticated user) to remove an `Enrollment` record.

These views define the core business logic endpoints for each microservice.

**1.2.4 Determine templates**

Django templates (`.html` files typically stored in a `templates` directory) are used to render
the User Interface (UI) presented to the end-user in a web browser. In a microservices
architecture, UI rendering can be handled in a few ways: each service renders its own
pages, a dedicated Frontend service/application handles all UI, or an API Gateway
aggregates data for a frontend. For simplicity, let's assume some services might render basic
HTML, or that there's an implied simple frontend interacting with the APIs.

Key templates needed would include:

1. **User-related Templates (Potentially served by `UserService` or a Frontend)**:


* `register.html`: A form for new users to sign up.
* `login.html`: A form for existing users to log in.
* `profile.html`: Displays the logged-in user's profile information.

2. **Course-related Templates (Potentially served by `CourseService` or a Frontend)**:


* `course_list.html`: Displays a list of available courses, likely with titles and brief
descriptions. Uses data fetched from `CourseService`.
* `course_detail.html`: Shows the full details of a single course, including description and
instructor. Might also show an "Enroll" button if the user isn't enrolled, potentially fetching
enrollment status from `EnrollmentService`.

3. **Enrollment-related Templates (Potentially served by `EnrollmentService` or a


Frontend)**:
* `my_courses.html`: Lists the courses the currently logged-in user is enrolled in. Fetches
data primarily from `EnrollmentService` and potentially enriches it with details from
`CourseService`.

These templates provide the visual interface for users to interact with the platform's
functionalities, using data supplied by the backend microservices.

**1.2.5 Determine REST API connecting services**

Communication *between* the microservices is crucial. Representational State Transfer


(REST) APIs using HTTP(S) and JSON are the standard way to achieve this. Each service
exposes endpoints (URLs) that other services (or a frontend) can call to request data or
trigger actions.

Key API endpoints based on the views defined earlier:

1. **`UserService` API Endpoints**:


* `POST /api/users/register`: Calls the `register` view.
* `POST /api/users/login`: Calls the `login` view, returns user info and/or token.
* `GET /api/users/{user_id}`: Calls `get_user_profile`. Used by other services to verify
users or get display names.
* `PUT /api/users/{user_id}`: Calls `update_user_profile`.

2. **`CourseService` API Endpoints**:


* `GET /api/courses`: Calls `list_courses`. Used by frontend or `EnrollmentService`.
* `GET /api/courses/{course_id}`: Calls `get_course_details`. Used by frontend or
`EnrollmentService`.
* `POST /api/courses`: Calls `create_course`. (Admin only)
* `PUT /api/courses/{course_id}`: Calls `update_course`. (Admin only)

3. **`EnrollmentService` API Endpoints**:


* `POST /api/enrollments`: Calls `enroll_in_course`. Expects `course_id` in the body, infers
`user_id` from auth token. Needs to internally call `UserService` (to validate token/user) and
`CourseService` (to check if course exists).
* `GET /api/users/{user_id}/enrollments`: Calls `list_user_enrollments`. Returns a list of
enrollment records (potentially just `course_id`s) for the given user.
* `DELETE /api/enrollments/{enrollment_id}`: Calls `unenroll_from_course`.

**Interaction Example**: When a user clicks "Enroll" on `course_detail.html` for course `C1`:
1. The frontend (or relevant service) makes a `POST` request to `/api/enrollments` on the
`EnrollmentService`, sending the `course_id` `C1` and the user's authentication token.
2. `EnrollmentService` receives the request.
3. It might call `GET /api/users/me` (or similar endpoint) on `UserService`, passing the token
to validate the user and get their `user_id`.
4. It might call `GET /api/courses/C1` on `CourseService` to confirm the course exists.
5. If both checks pass, it creates a new `Enrollment` record in its database with the `user_id`
and `course_id` `C1`.
6. It returns a success response (e.g., `201 Created`).

These REST APIs form the connective tissue of the microservice architecture, enabling
decoupled services to collaborate to fulfill user requests.

---

**1.3 Conclusion**

The analysis phase has resulted in a proposed architecture for the Online Course Platform
based on microservices implemented with Django. The system is decomposed into three
core services: `UserService`, `CourseService`, and `EnrollmentService`, each managing a
distinct functional domain. For each service, the primary data models (`models.py`),
business logic handlers (`views.py`), potential user interface templates (`templates`), and
inter-service communication mechanisms via REST APIs have been outlined.

This decomposition provides a foundation for building a modular and potentially scalable
system. While kept simple for this assignment, this structure highlights the benefits of
separating concerns. Each service can be developed, deployed, and scaled independently.
The reliance on well-defined REST APIs ensures that services interact in a standardized
way.

This design represents a simplified view. A real-world implementation would require


addressing further complexities such as robust error handling, asynchronous communication
patterns (e.g., message queues) for certain tasks, comprehensive security measures (API
keys, OAuth2/JWT), service discovery, and potentially an API Gateway to simplify client-side
interactions. However, the current analysis fulfills the requirement of defining a basic
microservice structure using Django for the Online Course Platform. The next steps would
involve the actual implementation of these services based on this design.

CHAPTER 2: DESIGN E-COMMERCE


SYSTEM WITH MICROSERVICES AND
DJANGO

2.1 Design services/components


The e-commerce system has been designed using a microservices architecture with Django
as the framework. The system is decomposed into three primary microservices, each
handling distinct business domains:

1. Accounts Service
This service manages user authentication and profile management, operating as an
independent domain with its own data storage.

Responsibilities:

●​ User registration
●​ User authentication (login/logout)
●​ Profile management
●​ Session handling

The accounts service has been implemented as a Django app with its own models, views,
templates, and URL configurations, ensuring separation of concerns. It provides
authentication services that other components can leverage.

2. Product Service (Book)

This service manages product information and search capabilities.

Responsibilities:
●​ Product information management
●​ Product categorization
●​ Product search functionality
●​ Image handling for products

The product service (implemented as the "book" app) maintains its own data model and
provides interfaces for retrieving product information, which is consumed by both the user
interface and other services.

3. Cart Service

This service manages shopping cart operations.

Responsibilities:

●​ Adding items to cart


●​ Removing items from cart
●​ Calculating cart totals
●​ Maintaining cart state

The cart service references products from the product service but maintains its own model
for cart state, demonstrating the loose coupling between microservices.
Service Interaction Pattern

The microservices are designed with the following interaction pattern:

●​ Independent data storage for each service


●​ REST API communication between services
●​ Shared authentication context via Django's session mechanism
●​ Context processors for cross-cutting concerns (e.g., cart count)

This pattern enables independent scaling and development of each service while
maintaining necessary integration points.

2.2 Design classes and methods in component


Accounts Service Design
Core Classes:

1.​ UserAccount Model​

○​ Extends Django's AbstractBaseUser


○​ Attributes: username, email, password (hashed), is_active, is_staff
○​ Customizes authentication fields with USERNAME_FIELD and
REQUIRED_FIELDS
2.​ UserAccountManager​

○​ Extends BaseUserManager
○​ Methods for creating standard and admin users
○​ Handles password hashing and validation
3.​ AuthService​

○​ Encapsulates authentication logic


○​ Provides methods to authenticate and validate users

Key Methods:

●​ register() - Handles user registration with form validation


●​ login_view() - Authenticates users and establishes sessions
●​ logout_view() - Terminates user sessions

The accounts service implements the Repository pattern through Django's ORM, separating
data access from business logic.

Product Service Design

Core Classes:

1.​ Item Model


○​ Attributes: name, category, price, product_image, average_rating
○​ Methods for string representation and price conversion

Key Methods:

●​ search() - Implements product search with filtering


●​ get_price_as_decimal() - Handles decimal type conversion for prices

The product service uses Query Objects pattern in its search implementation, encapsulating
complex query logic.
Cart Service Design

Core Classes:

1.​ Cart Model​

○​ References UserAccount through ForeignKey


○​ Tracks creation and update timestamps
○​ Methods for calculating total_price
2.​ CartItem Model​

○​ Links Cart and Item through ForeignKeys


○​ Tracks quantity of each item
○​ Methods for calculating item subtotals
Key Methods:

●​ cart_view() - Retrieves and displays cart contents


●​ add_to_cart() - Adds products to user cart
●​ cart_remove() - Removes items from cart
●​ cart_count() (context processor) - Provides cart count across templates

The cart service implements the Aggregate pattern, with Cart acting as the root entity that
encapsulates a collection of CartItems.

2.3 Design API


The system implements a RESTful API design following Django's URL routing patterns, with
clear separation between different service domains.

URL Structure

1.​ Accounts API:​

○​ /accounts/register/ - User registration endpoint


○​ /accounts/login/ - Authentication endpoint
○​ /accounts/logout/ - Session termination endpoint
2.​ Product API:​

○​ /book/item/search - Product search endpoint with filtering capabilities


3.​ Cart API:​

○​ /cart/ - Cart view endpoint


○​ /cart/add/<int:item_id>/ - Add to cart endpoint
○​ /cart/remove/<int:customerId>/ - Remove from cart endpoint

API Implementation Approach

The API is implemented using:

1.​ Django Views - Function-based views that handle HTTP requests and responses
2.​ CSRF Protection - Security measures for form submissions
3.​ JSON Responses - For asynchronous operations (particularly in the registration
form)
4.​ URL Namespacing - With app_name specification to avoid naming conflicts

Cross-Service Communication

Services communicate through:

1.​ Direct Model References - CartItem references Item model from the product service
2.​ Context Processors - The cart service provides a cart_count context processor for
use in templates
3.​ Django's Authentication Middleware - For user context sharing

The API design follows RESTful principles with resources identified by URLs, HTTP
methods determining operations, and appropriate status codes for responses.

2.4 Conclusion
The microservices architecture implemented in this Django e-commerce system offers
several advantages:

1.​ Modularity - Each service operates independently, allowing focused development


and maintenance
2.​ Scalability - Services can be scaled independently based on demand
3.​ Resilience - Failures in one service have limited impact on others
4.​ Technology Flexibility - Different services could potentially use different technology
stacks

The system also has some design considerations that warrant attention:

1.​ Data Consistency - With separate databases, ensuring consistency across services
requires careful design
2.​ Deployment Complexity - Microservices bring increased deployment and
operational complexity
3.​ Transaction Management - Cross-service transactions are challenging and not fully
addressed

Potential improvements for future iterations:

1.​ Message Queue Implementation - For asynchronous communication between


services
2.​ API Gateway - To provide a unified entry point for client applications
3.​ Service Discovery - For dynamic service location as the system scales
4.​ JWT Authentication - For more robust cross-service authentication

The current design successfully demonstrates the principles of microservices architecture


while leveraging Django's strengths in rapid application development, ORM capabilities, and
template system. The separation into accounts, product, and cart services provides a
foundation that can be extended with additional microservices like payment processing,
order management, and recommendation systems.

CHAPTER 3: AI IN E-COMMERCE
3.1 Application of Deep Learning in E-Commerce
Deep learning technology has transformed modern e-commerce platforms by enabling
sophisticated data analysis and personalization capabilities. For our Django-based
microservices e-commerce system, integrating deep learning presents strategic
opportunities to enhance user experience and business outcomes.

Strategic Applications for Our Platform

The key deep learning applications relevant to our e-commerce system include:

Product Image Analysis: Convolutional Neural Networks (CNNs) can analyze product
images to extract features for improved search, similarity matching, and automated
categorization. This would enhance our existing product service by adding visual search
capabilities, allowing users to find products similar to those they are viewing.

Natural Language Processing for Product Descriptions: Transformer-based models such


as BERT can extract semantic meaning from product descriptions, enabling more intelligent
search functionality that understands user intent rather than simply matching keywords.

User Behavior Prediction: Recurrent Neural Networks (RNNs) and Long Short-Term
Memory (LSTM) networks can analyze sequential user interactions to predict likely next
actions, enabling proactive recommendations and personalized user journeys.

Dynamic Pricing Optimization: Deep learning models can analyze market conditions,
competitor pricing, demand patterns, and user willingness-to-pay to suggest optimal pricing
strategies for products.

Architectural Considerations

To integrate these capabilities into our existing microservices architecture, we propose a


dedicated AI service that interfaces with our other services:

1.​ AI Service Layer: A new microservice that encapsulates all deep learning
functionality, exposing APIs for other services to consume
2.​ Data Pipeline: A system for collecting, preprocessing, and feeding data to the deep
learning models
3.​ Model Repository: A storage and versioning system for trained models
4.​ Inference Engine: A scalable system for executing predictions based on the trained
models

This approach maintains the separation of concerns principle established in our


microservices architecture while adding powerful new capabilities.

3.2 Sentiment Analysis


Sentiment analysis represents a critical capability for understanding customer opinions and
improving product offerings. For our e-commerce platform, implementing sentiment analysis
enables us to extract valuable insights from user-generated content.
Analysis Approach

We propose a multi-level sentiment analysis system:

Document-Level Analysis: Analyzing overall sentiment of reviews and comments to


categorize them as positive, negative, or neutral.

Aspect-Based Analysis: Extracting specific product aspects (e.g., "battery life," "user
interface") and the associated sentiments to provide granular insights into product strengths
and weaknesses.

Emotion Detection: Going beyond basic sentiment polarity to detect specific emotions (joy,
anger, disappointment) for more nuanced understanding of customer responses.

Technical Design

The sentiment analysis system will be designed with the following components:

1.​ Data Collection Module: Interfaces with the product service to access reviews,
comments, and other user-generated content
2.​ Preprocessing Pipeline: Handles text normalization, tokenization, and cleaning
3.​ Feature Extraction: Transforms text into numerical representations using
embeddings
4.​ Sentiment Classification Models: A combination of models including:
○​ Fine-tuned transformer model (e.g., RoBERTa) for high-accuracy
classification
○​ Lightweight models for real-time analysis
5.​ Results Storage: A database schema for storing and querying sentiment analysis
results

The sentiment analysis capability will be exposed through APIs that other services can
consume, maintaining the loose coupling principle of our microservices architecture.

3.3 Applying Sentiment Analysis for Recommendation


Leveraging sentiment analysis to enhance recommendation systems represents a significant
opportunity to improve customer experience and increase conversion rates. Traditional
collaborative filtering approaches can be augmented with sentiment data to create more
nuanced and effective recommendations.

Sentiment-Enhanced Recommendation Design

We propose a hybrid recommendation system with the following components:

1.​ User Preference Model: Captures explicit preferences (ratings) and implicit
preferences (browsing behavior)
2.​ Sentiment-Augmented Product Representation: Enriches product profiles with
sentiment data extracted from reviews
3.​ Aspect-Based Matching: Matches users to products based on aspects they have
positively mentioned in previous reviews
4.​ Sentiment-Aware Ranking: Adjusts recommendation scores based on sentiment
trends

Architectural Integration

The recommendation system will be integrated with our existing microservices through:

1.​ Data Integration Layer: Collects user activity data from the accounts service,
product information from the product service, and cart information from the cart
service
2.​ Recommendation API: Provides endpoints for:
○​ Personalized product recommendations
○​ "Customers also bought" recommendations
○​ Category-specific recommendations
3.​ Real-Time Event Processing: Captures and processes user actions to update
recommendations dynamically

The recommendation service will maintain its own data store for user preferences and
precomputed recommendations, while accessing sentiment data through APIs provided by
the sentiment analysis component.

3.4 Deployment
Deploying AI capabilities within our microservices architecture requires careful planning to
ensure performance, scalability, and maintainability.

Deployment Strategy

We propose a phased deployment approach:

1.​ Development and Training Environment: A separate environment for model


development, training, and experimentation
2.​ Staging Deployment: Integration with a copy of production data for testing and
evaluation
3.​ Production Deployment: Gradual rollout of AI capabilities to production users

Infrastructure Design

The AI components will be deployed using the following infrastructure:

1.​ Container-Based Deployment: Docker containers for AI services to ensure


consistency across environments
2.​ Kubernetes Orchestration: For scaling and managing the AI service containers
3.​ Model Serving Infrastructure: TensorFlow Serving or similar technology for efficient
model inference
4.​ API Gateway: To route requests to appropriate AI services and handle authentication
5.​ Monitoring and Logging: Comprehensive monitoring of model performance,
inference times, and error rates

Performance Considerations

To ensure optimal performance:

1.​ Asynchronous Processing: Heavy computational tasks will be performed


asynchronously using message queues
2.​ Caching Layer: Frequently requested predictions will be cached to reduce latency
3.​ Model Optimization: Models will be optimized for inference using techniques such
as quantization and pruning
4.​ Autoscaling: The system will automatically scale based on demand

3.5 Conclusion
The integration of AI capabilities, particularly deep learning, sentiment analysis, and
recommendation systems, represents a significant enhancement to our e-commerce
platform. These technologies enable a more personalized, responsive, and intelligent
shopping experience.

The proposed design adheres to the microservices principles established in our architecture
while introducing new capabilities through well-defined interfaces. By maintaining separation
of concerns and loose coupling, we ensure that our AI components can evolve
independently of the core e-commerce functionality.

The sentiment analysis and recommendation systems will work together to create a virtuous
cycle of data collection, insight generation, and improved user experience. By understanding
customer sentiments at a granular level, we can provide more relevant recommendations,
which in turn leads to higher engagement and more sentiment data.

Key benefits of this approach include:

1.​ Enhanced personalization leading to higher conversion rates


2.​ Deeper insights into customer preferences and product performance
3.​ Improved search capabilities through natural language understanding
4.​ The ability to identify emerging trends through sentiment analysis

Looking forward, this architecture provides a foundation for future AI enhancements, such as
conversational interfaces, fraud detection systems, and predictive inventory management.
The modular nature of our design ensures that we can continue to add capabilities as
technologies mature and business needs evolve.

By thoughtfully integrating AI technologies into our e-commerce platform, we create a


system that not only meets current customer expectations but can adapt to the rapidly
changing landscape of online retail.
CHAPTER 4: IMPLEMENTATION AND
DEPLOYMENT

AI Recommendation System Overview


Your recommendation system uses sentiment analysis to analyze product reviews and
generate personalized recommendations for users. Here's how it works:

1. Sentiment Analysis Component

The core of your AI system is in book/services/sentiment_service.py, which:

●​ Uses NLTK's VADER (Valence Aware Dictionary and Sentiment Reasoner) for
sentiment analysis
●​ Processes text by removing stopwords and punctuation
●​ Analyzes the sentiment of product reviews and assigns scores between -1 (very
negative) and +1 (very positive)

2. Recommendation Service

In book/services/recommendation_service.py, you've implemented


recommendation logic that:

●​ Retrieves top-rated items based on sentiment scores


●​ Generates personalized recommendations for users based on their review history
●​ Identifies categories a user has positively reviewed and suggests similar products
●​ Falls back to generally well-reviewed products when user-specific data isn't available

3. Integration Points

Your AI recommendation system is integrated at several points:

●​ When users submit reviews (item_detail view), their reviews are analyzed for
sentiment
●​ The recommendations view provides personalized product suggestions
●​ The search page shows recommended items alongside search results
●​ You display sentiment indicators on reviews (positive/neutral/negative tags)

4. User Experience Benefits

The system enhances the shopping experience by:

●​ Helping users discover products they're likely to enjoy based on sentiment patterns
●​ Highlighting products with positive sentiment across all users
●​ Visually indicating the sentiment of reviews to help users quickly assess product
quality
●​ Creating a more personalized shopping experience

Technical Implementation Details


Your implementation uses:

1.​ The Review model with a sentiment_score field to store analysis results
2.​ The SentimentService class that handles text preprocessing and analysis
3.​ The RecommendationService class that generates personalized
recommendations
4.​ Template integration showing sentiment indicators and recommended products

The system is well integrated with your Django application, with dedicated views for
recommendations and sentiment analysis logic that's applied when reviews are submitted.

This is a sophisticated feature that adds real value to your e-commerce site by leveraging AI
to improve product discovery and user satisfaction.

1.​Backend code

​ from django.db import models


from django.conf import settings # Add this import for AUTH_USER_MODEL
from decimal import Decimal

# Make sure Item model is defined BEFORE Review model


class Item(models.Model):
name = models.CharField(max_length=200)
category = models.CharField(max_length=100)
price = models.DecimalField(max_digits=10, decimal_places=2)
product_image = models.ImageField(upload_to='items/', blank=True,
null=True)
average_rating = models.DecimalField(max_digits=3, decimal_places=1,
default=0.0)

def __str__(self):
return self.name

def get_price_as_decimal(self):
# If self.price is a Decimal128
if hasattr(self.price, 'to_decimal'):
return Decimal(self.price.to_decimal())
return self.price

class Review(models.Model):
item = models.ForeignKey(Item, on_delete=models.CASCADE,
related_name='reviews')
user = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)
text = models.TextField()
rating = models.IntegerField(choices=[(1, '1'), (2, '2'), (3, '3'), (4,
'4'), (5, '5')])
sentiment_score = models.FloatField(default=0.0) # Will store our
sentiment analysis result
created_at = models.DateTimeField(auto_now_add=True)

def __str__(self):
return f"Review by {self.user.username} for {self.item.name}"

from django.shortcuts import render, redirect


from django.contrib.auth import authenticate, login, logout
from django.contrib import messages
import logging
from django.shortcuts import render
from django.db.models import Q, Count
from django.utils import timezone

from .models import Item


from django.shortcuts import render, redirect, get_object_or_404
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.http import JsonResponse
from django.db.models import Q, Avg
from .models import Item, Review
from .forms import ReviewForm
from .services.sentiment_service import SentimentService
from .services.recommendation_service import RecommendationService
from django.http import JsonResponse
from django.db import connections
from django.db.utils import OperationalError

logger = logging.getLogger('book')
# The search function you already have
# Modify the search function in book/views.py
def search(request):
keyword = request.GET.get('keyword', '')
items = []

try:
if keyword:
# Filter items by name or category that contain the keyword
(case-insensitive)
items = Item.objects.filter(
Q(name__icontains=keyword) | Q(category__icontains=keyword)
)
else:
# If no keyword provided, display all items
items = Item.objects.all()

# Add some recommended items if we have a user


recommended_items = []
if request.user.is_authenticated:
try:
recommended_items =
RecommendationService.get_recommendations_for_user(
user=request.user,
limit=4
)
except Exception as e:
logger.error(f"Error getting recommendations: {str(e)}")
# Continue even if recommendations fail
recommended_items = []

return render(request, 'search.html', {


'items': items,
'recommended_items': recommended_items
})

except Exception as e:
logger.error(f"Database error in search view: {str(e)}")
messages.error(request, "Sorry, we encountered a problem connecting
to our database. Please try again later.")
return render(request, 'search.html', {
'items': [],
'recommended_items': [],
'error': "Database connection error. Please try again later."
})
def item_detail(request, item_id):
"""View for displaying item details and reviews"""
item = get_object_or_404(Item, pk=item_id)
reviews = item.reviews.all().order_by('-created_at')
review_form = ReviewForm()

if request.method == 'POST' and request.user.is_authenticated:


review_form = ReviewForm(request.POST)
if review_form.is_valid():
review = review_form.save(commit=False)
review.item = item
review.user = request.user

# Analyze sentiment
sentiment_score =
SentimentService.analyze_sentiment(review.text)
review.sentiment_score = sentiment_score

review.save()

# Update item's average rating


item.average_rating =
item.reviews.aggregate(Avg('rating'))['rating__avg']
item.save()

messages.success(request, "Thank you for your review!")


return redirect('item_detail', item_id=item.id)

# Get recommended items based on this item


similar_items = Item.objects.filter(
category=item.category
).exclude(
id=item.id
).order_by('-average_rating')[:4]

context = {
'item': item,
'reviews': reviews,
'review_form': review_form,
'similar_items': similar_items
}

return render(request, 'book/item_detail.html', context)


# Update this function in book/views.py
def recommendations(request):
"""View for displaying personalized recommendations"""
try:
# Get top-rated items as recommendations
recommended_items =
Item.objects.all().order_by('-average_rating')[:8]

# Get trending items (most recently added)


trending_items = Item.objects.all().order_by('-id')[:4]

context = {
'recommended_items': recommended_items,
'trending_items': trending_items,
}

return render(request, 'book/recommendations.html', context)


except Exception as e:
logger.error(f"Error in recommendations view: {str(e)}")
messages.error(request, "An error occurred while loading
recommendations. Please try again later.")
return redirect('accounts:index') # Redirect to home page on error

# Add this function to book/views.py to check database connection


def db_health_check(request):
"""
Simple view to check if the database connection is working.
Access via /book/db-health/ after adding to urls.py
"""
try:
# Try to connect to the database
conn = connections['default']
conn.cursor()

# Try a simple query


test_query = Item.objects.first()

db_status = "Database connection successful!"


status_code = 200
except OperationalError as e:
# Handle database connection error
db_status = f"Database connection failed: {str(e)}"
status_code = 500
except Exception as e:
# Handle other exceptions
db_status = f"Error checking database: {str(e)}"
status_code = 500

return JsonResponse({
'status': db_status,
'engine': connections['default'].settings_dict['ENGINE'],
'name': connections['default'].settings_dict['NAME'],
'timestamp': timezone.now().isoformat(),
}, status=status_code)

# Add this to your urls.py:


# path('db-health/', views.db_health_check, name='db_health_check'),

# book/services/recommendation_service.py
from django.db.models import Avg, Count
from book.models import Item, Review

class RecommendationService:
"""Service for generating product recommendations based on sentiment
analysis"""

@staticmethod
def get_top_rated_items(limit=5, category=None):
"""
Get items with the highest average ratings

Args:
limit: Number of items to return
category: Optional category to filter by

Returns:
List of items sorted by average rating
"""
try:
items_query = Item.objects.all()

if category:
items_query = items_query.filter(category__iexact=category)

# Order by average_rating
return items_query.order_by('-average_rating')[:limit]
except Exception as e:
# If anything goes wrong, return an empty list
return []
@staticmethod
def get_recommendations_for_user(user, limit=5):
"""
Get personalized recommendations for a user

Args:
user: User object to get recommendations for
limit: Number of items to recommend

Returns:
List of recommended items
"""
try:
# For simplicity, just return top-rated items
return RecommendationService.get_top_rated_items(limit)
except Exception as e:
# If anything goes wrong, return an empty list
return []

from django.urls import path


from . import views

urlpatterns = [
path('item/search', views.search, name='search'),
path('item/<int:item_id>/', views.item_detail, name='item_detail'),
path('recommendations/', views.recommendations, name='recommendations'),
path('db-health/', views.db_health_check, name='db_health_check'),
]

from django import forms


from .models import Review

class ReviewForm(forms.ModelForm):
class Meta:
model = Review
fields = ['text', 'rating']
widgets = {
'text': forms.Textarea(attrs={'rows': 4, 'placeholder': 'Write
your review here...'}),
'rating': forms.Select(choices=[(1, '1 - Poor'), (2, '2 -
Fair'), (3, '3 - Good'), (4, '4 - Very Good'), (5, '5 - Excellent')])
}
labels = {
'text': 'Your Review',
'rating': 'Rating'
}
2.​Frontend code
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,
initial-scale=1.0">
<title>Personalized Recommendations | ECom2 Shop</title>
<link
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/a
ll.min.css" rel="stylesheet">
<style>
:root {
--primary-color: #1e3a8a;
--secondary-color: #3b82f6;
--accent-color: #f43f5e;
--success-color: #10b981;
--background-color: #f3f4f6;
--card-background: #ffffff;
--text-color: #1f2937;
--border-radius: 8px;
--shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}

* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

body {
font-family: 'Segoe UI', system-ui, sans-serif;
background-color: var(--background-color);
color: var(--text-color);
line-height: 1.6;
}

.header {
background: var(--primary-color);
padding: 1rem 0;
position: sticky;
top: 0;
z-index: 100;
box-shadow: var(--shadow);
}
.header-content {
max-width: 1400px;
margin: 0 auto;
padding: 0 2rem;
display: flex;
justify-content: space-between;
align-items: center;
}

.logo {
color: white;
font-size: 1.5rem;
font-weight: bold;
text-decoration: none;
display: flex;
align-items: center;
gap: 0.5rem;
}

.nav-links {
display: flex;
gap: 1.5rem;
}

.nav-link {
color: white;
text-decoration: none;
transition: all 0.3s ease;
}

.nav-link:hover {
color: var(--accent-color);
}

.container {
max-width: 1200px;
margin: 2rem auto;
padding: 0 1rem;
}

.hero {
background: linear-gradient(135deg, var(--primary-color),
var(--secondary-color));
color: white;
padding: 3rem 2rem;
border-radius: var(--border-radius);
margin-bottom: 2rem;
box-shadow: var(--shadow);
text-align: center;
}

.hero h1 {
font-size: 2.5rem;
margin-bottom: 1rem;
}

.hero p {
font-size: 1.1rem;
max-width: 700px;
margin: 0 auto;
opacity: 0.9;
}

.section {
margin-bottom: 3rem;
}

.section-title {
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 1.5rem;
color: var(--primary-color);
margin-bottom: 1.5rem;
padding-bottom: 0.5rem;
border-bottom: 2px solid var(--secondary-color);
}

.products-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px,
1fr));
gap: 2rem;
}

.product-card {
background: white;
border-radius: var(--border-radius);
overflow: hidden;
box-shadow: var(--shadow);
transition: all 0.3s ease;
height: 100%;
display: flex;
flex-direction: column;
}

.product-card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 15px rgba(0, 0, 0, 0.1);
}

.product-card-image {
width: 100%;
height: 200px;
object-fit: cover;
}

.product-card-content {
padding: 1.5rem;
flex-grow: 1;
display: flex;
flex-direction: column;
}

.product-category {
font-size: 0.8rem;
color: var(--secondary-color);
text-transform: uppercase;
letter-spacing: 1px;
margin-bottom: 0.5rem;
}

.product-card-title {
font-size: 1.2rem;
margin-bottom: 0.5rem;
color: var(--primary-color);
}

.product-card-price {
font-weight: bold;
color: var(--primary-color);
margin-bottom: 1rem;
}

.product-card-rating {
display: flex;
align-items: center;
gap: 0.3rem;
margin-bottom: 1rem;
}

.star {
color: #fbbf24;
}

.product-card-button {
width: 100%;
background: var(--secondary-color);
color: white;
border: none;
padding: 0.75rem;
border-radius: var(--border-radius);
cursor: pointer;
transition: all 0.3s ease;
text-align: center;
text-decoration: none;
display: block;
margin-top: auto;
}

.product-card-button:hover {
background: #2563eb;
}

.no-items {
text-align: center;
padding: 2rem;
background: white;
border-radius: var(--border-radius);
box-shadow: var(--shadow);
}

.no-items i {
font-size: 3rem;
color: var(--secondary-color);
margin-bottom: 1rem;
}

.sentiment-tag {
display: inline-block;
padding: 0.25rem 0.5rem;
border-radius: 999px;
font-size: 0.75rem;
font-weight: 600;
margin-left: 0.5rem;
}

.sentiment-positive {
background-color: rgba(16, 185, 129, 0.1);
color: #10b981;
}

.sentiment-neutral {
background-color: rgba(107, 114, 128, 0.1);
color: #6b7280;
}

.sentiment-negative {
background-color: rgba(239, 68, 68, 0.1);
color: #ef4444;
}

.info-box {
background: white;
border-radius: var(--border-radius);
padding: 1.5rem;
box-shadow: var(--shadow);
margin-bottom: 2rem;
}

.info-box h3 {
color: var(--primary-color);
margin-bottom: 0.5rem;
display: flex;
align-items: center;
gap: 0.5rem;
}

.info-box p {
color: #4b5563;
}

@media (max-width: 768px) {


.products-grid {
grid-template-columns: repeat(auto-fill, minmax(220px,
1fr));
gap: 1rem;
}
.hero {
padding: 2rem 1rem;
}

.hero h1 {
font-size: 1.8rem;
}
}
</style>
</head>
<body>
<header class="header">
<div class="header-content">
<a href="{% url 'accounts:index' %}" class="logo">
<i class="fas fa-shopping-bag"></i>
ECom2 Shop
</a>
<div class="nav-links">
<a href="{% url 'search' %}" class="nav-link">
<i class="fas fa-search"></i> Shop
</a>
<a href="{% url 'cart:cart_view' %}" class="nav-link">
<i class="fas fa-shopping-cart"></i>
<span class="cart-count">{{ cart_count|default:"0"
}}</span>
</a>
</div>
</div>
</header>

<div class="container">
<div class="hero">
<h1>Personalized Recommendations</h1>
<p>Discover products tailored to your interests based on
our sentiment analysis AI</p>
</div>

<div class="info-box">
<h3><i class="fas fa-robot"></i> Powered by AI</h3>
<p>Our recommendations are powered by sentiment analysis
AI that analyzes customer reviews to understand what products people
truly love. The more you interact with our store, the better our
recommendations become!</p>
</div>

<div class="section">
<h2 class="section-title"><i class="fas fa-thumbs-up"></i>
Recommended for You</h2>
<!-- Modify the section that displays recommendations in
book/templates/book/recommendations.html -->

{% if recommended_items %}
<div class="products-grid">
{% for item in recommended_items %}
<div class="product-card">
<img src="{{ item.product_image.url }}" alt="{{
item.name }}" class="product-card-image">
<div class="product-card-content">
<div class="product-category">{{ item.category
}}</div>
<h3 class="product-card-title">{{ item.name
}}</h3>
<p class="product-card-price">${{ item.price
}}</p>
<div class="product-card-rating">
{% for i in "12345" %}
{% if forloop.counter <=
item.average_rating %}
<i class="fas fa-star star"></i>
{% elif forloop.counter <=
item.average_rating|add:0.5 %}
<i class="fas fa-star-half-alt star"></i>
{% else %}
<i class="far fa-star star"></i>
{% endif %}
{% endfor %}

{% if item.average_rating >= 4 %}
<span class="sentiment-tag
sentiment-positive">Highly Rated</span>
{% endif %}
</div>
<a href="{% url 'item_detail' item.id %}"
class="product-card-button">View Details</a>
</div>
</div>
{% endfor %}
</div>
{% else %}
<div class="no-items">
<i class="fas fa-search"></i>
<h3>No recommendations yet</h3>
<p>Browse and review some products to get personalized
recommendations</p>
</div>
{% endif %}

<!-- Similar change for the trending_items section -->


{% if trending_items %}
<div class="products-grid">
{% for item in trending_items %}
<div class="product-card">
<img src="{{ item.product_image.url }}" alt="{{
item.name }}" class="product-card-image">
<div class="product-card-content">
<div class="product-category">{{ item.category
}}</div>
<h3 class="product-card-title">{{ item.name
}}</h3>
<p class="product-card-price">${{ item.price
}}</p>
<div class="product-card-rating">
{% for i in "12345" %}
{% if forloop.counter <=
item.average_rating %}
<i class="fas fa-star star"></i>
{% elif forloop.counter <=
item.average_rating|add:0.5 %}
<i class="fas fa-star-half-alt star"></i>
{% else %}
<i class="far fa-star star"></i>
{% endif %}
{% endfor %}
</div>
<a href="{% url 'item_detail' item.id %}"
class="product-card-button">View Details</a>
</div>
</div>
{% endfor %}
</div>
{% else %}
<div class="no-items">
<i class="fas fa-fire"></i>
<h3>No trending items yet</h3>
<p>Check back soon for the hottest products!</p>
</div>
{% endif %}
</div>
<div class="section">
<h2 class="section-title"><i class="fas fa-fire"></i>
Trending Now</h2>

<!-- Fix for the trending items section -->


{% if trending_items %}
<div class="products-grid">
{% for item in trending_items %}
<div class="product-card">
<img src="{{ item.product_image.url }}" alt="{{
item.name }}" class="product-card-image">
<div class="product-card-content">
<div class="product-category">{{ item.category
}}</div>
<h3 class="product-card-title">{{ item.name
}}</h3>
<p class="product-card-price">${{ item.price
}}</p>
<div class="product-card-rating">
{% for i in "12345" %}
{% if forloop.counter <=
item.average_rating|default:0 %}
<i class="fas fa-star star"></i>
{% elif forloop.counter <=
item.average_rating|add:0.5|default:0 %}
<i class="fas fa-star-half-alt star"></i>
{% else %}
<i class="far fa-star star"></i>
{% endif %}
{% endfor %}
<span>({{ item.review_count|default:"0" }}
reviews)</span>
</div>
<a href="{% url 'item_detail' item.id %}"
class="product-card-button">View Details</a>
</div>
</div>
{% endfor %}
</div>
{% else %}
<div class="no-items">
<i class="fas fa-fire"></i>
<h3>No trending items yet</h3>
<p>Check back soon for the hottest products!</p>
</div>
{% endif %}
</div>
</div>
</body>
</html>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,
initial-scale=1.0">
<title>Shop | EcoShop</title>
<link
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/a
ll.min.css" rel="stylesheet">
<style>
/* Base Styles */
#cartNotification {
z-index: 9999;
}

:root {
--primary-color: #1e3a8a; /* Navy blue */
--secondary-color: #3b82f6; /* Sky blue */
--accent-color: #f43f5e; /* Coral pink */
--success-color: #10b981; /* Green */
--background-color: #f3f4f6; /* Light grey */
--card-background: #ffffff;
--text-color: #1f2937; /* Dark grey */
--border-radius: 8px;
--shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}

* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

body {
font-family: 'Segoe UI', system-ui, sans-serif;
background-color: var(--background-color);
color: var(--text-color);
line-height: 1.6;
}

/* Header and Search Section */


.header {
background: var(--primary-color);
padding: 1rem 0;
position: sticky;
top: 0;
z-index: 100;
box-shadow: var(--shadow);
}

.header-content {
max-width: 1400px;
margin: 0 auto;
padding: 0 2rem;
display: flex;
justify-content: space-between;
align-items: center;
}

.logo {
color: white;
font-size: 1.5rem;
font-weight: bold;
text-decoration: none;
display: flex;
align-items: center;
gap: 0.5rem;
}

.search-container {
background: white;
border-radius: var(--border-radius);
padding: 1rem 2rem;
margin: 2rem auto;
max-width: 800px;
box-shadow: var(--shadow);
}

.search-form {
display: flex;
gap: 1rem;
}

.search-input {
flex: 1;
padding: 0.8rem 1.2rem;
border: 2px solid #e5e7eb;
border-radius: var(--border-radius);
font-size: 1rem;
transition: all 0.3s ease;
}

.search-input:focus {
border-color: var(--secondary-color);
outline: none;
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2);
}

.search-btn {
background: var(--secondary-color);
color: white;
border: none;
padding: 0 2rem;
border-radius: var(--border-radius);
cursor: pointer;
transition: all 0.3s ease;
}

.search-btn:hover {
background: #2563eb;
transform: translateY(-2px);
}

/* Main Content */
.container {
max-width: 1400px;
margin: 0 auto;
padding: 2rem;
}

/* Grid Layout */
.items-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px,
1fr));
gap: 2rem;
margin-top: 2rem;
}

/* Item Card */
.item-card {
background: var(--card-background);
border-radius: var(--border-radius);
overflow: hidden;
box-shadow: var(--shadow);
transition: all 0.3s ease;
animation: fadeInUp 0.5s ease-out backwards;
}

.item-card:hover {
transform: translateY(-5px);
box-shadow: 0 8px 15px rgba(0, 0, 0, 0.1);
}

.item-image {
width: 100%;
height: auto; /* Maintain aspect ratio */
aspect-ratio: 4 / 3; /* Optional: Helps keep consistent
sizing across images */
object-fit: cover; /* Ensure images fill area without
stretching */
border-bottom: 2px solid var(--secondary-color); /*
Optional: Add a border for better separation */
}

.item-content {
padding: 1.5rem;
}

.item-category {
font-size: 0.8rem;
color: var(--secondary-color);
text-transform: uppercase;
letter-spacing: 1px;
margin-bottom: 0.5rem;
}

.item-title {
font-size: 1.2rem;
margin-bottom: 0.5rem;
color: var(--text-color);
}

.item-price {
font-size: 1.3rem;
font-weight: bold;
color: var(--primary-color);
margin-bottom: 1rem;
}

.item-meta {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 1rem;
font-size: 0.9rem;
color: #6b7280;
}

.rating {
display: flex;
align-items: center;
gap: 0.3rem;
}

.star {
color: #fbbf24;
}

.comments {
display: flex;
align-items: center;
gap: 0.3rem;
}

/* Add to Cart Button */


.add-to-cart {
width: 100%;
background: var(--primary-color);
color: white;
border: none;
padding: 0.8rem;
border-radius: var(--border-radius);
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
gap: 0.5rem;
transition: all 0.3s ease;
}

.add-to-cart:hover {
background: #1e40af;
}

/* Cart Notification */
.cart-notification {
position: fixed;
top: 2rem;
right: 2rem;
background: var(--success-color);
color: white;
padding: 1rem 2rem;
border-radius: var(--border-radius);
box-shadow: var(--shadow);
display: flex;
align-items: center;
gap: 0.5rem;
transform: translateX(200%);
transition: transform 0.3s ease;
}

.cart-notification.show {
transform: translateX(0);
}

/* Animations */
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}

.item-card {
animation-delay: calc(var(--animation-order) * 0.1s);
}

/* Responsive Design */
@media (max-width: 768px) {
.header-content {
flex-direction: column;
gap: 1rem;
padding: 1rem;
}

.search-container {
margin: 1rem;
padding: 1rem;
}

.search-form {
flex-direction: column;
}

.search-btn {
width: 100%;
padding: 0.8rem;
}

.container {
padding: 1rem;
}

.items-grid {
grid-template-columns: 1fr;
gap: 1rem;
}
}
</style>
</head>
<body>
<header class="header">
<div class="header-content">
<a href="{% url 'accounts:index' %}" class="logo">
<i class="fas fa-shopping-bag"></i>
ECom2 Shop
</a>
<a href="{% url 'cart:cart_view' %}" style="color: white;
text-decoration: none;">
<i class="fas fa-shopping-cart"></i>
<span class="cart-count">{{ cart_count|default:"0"
}}</span>
</a>

</div>
</header>
<div class="search-container">
<form class="search-form" action="{% url 'search' %}"
method="get">
<input type="text" name="keyword" class="search-input"
placeholder="Search for items...">
<button type="submit" class="search-btn">
<i class="fas fa-search"></i> Search
</button>
</form>
</div>
<main class="container">
<div class="items-grid">
{% for item in items %}
<div class="item-card">
{% comment %}
<a href="{% url 'item_detail' item.id %}">
{% endcomment %}
<img class="item-image" src="{{ item.product_image.url
}}" alt="Item Image">
{% comment %}
</a>
{% endcomment %}
<div class="item-content">
<div class="item-category">{{
item.category|default:"Book" }}</div>
<h3 class="item-title">{{ item.name }}</h3>
<div class="item-meta">
<div class="rating">
<i class="fas fa-star star"></i>
<span>{{ item.average_rating|default:"No
ratings" }}</span>
<!-- You can add a count for ratings if
available -->
</div>
<div class="comments">
<i class="fas fa-comment"></i>
<span>12</span>
</div>
</div>
<div class="item-price">$ {{ item.price }}</div>
<form action="{% url 'cart:add_to_cart' item.id %}"
method="post" class="add-to-cart-form">
{% csrf_token %}
<button type="submit" class="add-to-cart">
<i class="fas fa-cart-plus"></i>
Add to Cart
</button>
</form>
</div>
</div>
{% endfor %}
</div>
# This is a code snippet to add to book/templates/search.html
# Add this section just before the closing </main> tag

{% if recommended_items %}
<div class="section">
<h2 class="section-title" style="font-size: 1.5rem; color:
var(--primary-color); margin-top: 2rem; padding-bottom: 0.5rem;
border-bottom: 2px solid var(--secondary-color);">
<i class="fas fa-thumbs-up"></i> Recommended for You
</h2>

<div class="items-grid">
{% for item in recommended_items %}
<div class="item-card">
<a href="{% url 'item_detail' item.id %}">
<img class="item-image" src="{{
item.product_image.url }}" alt="Item Image">
</a>
<div class="item-content">
<div class="item-category">{{
item.category|default:"Book" }}</div>
<h3 class="item-title">{{ item.name }}</h3>
<div class="item-meta">
<div class="rating">
<i class="fas fa-star star"></i>
<span>{{ item.average_rating|default:"No
ratings" }}</span>
</div>
<div class="comments">
<i class="fas fa-comment"></i>
<span>{{ item.reviews.count }}</span>
</div>
</div>
<div class="item-price">$ {{ item.price }}</div>
<form action="{% url 'cart:add_to_cart' item.id
%}" method="post" class="add-to-cart-form">
{% csrf_token %}
<button type="submit" class="add-to-cart">
<i class="fas fa-cart-plus"></i>
Add to Cart
</button>
</form>
</div>
</div>
{% endfor %}
</div>
</div>
{% endif %}
</main>

<div class="cart-notification" id="cartNotification">


<i class="fas fa-check-circle"></i>
Item added to cart!
</div>

<script>
// JavaScript for handling cart notifications and animations
document.querySelectorAll('.add-to-cart-form').forEach(form => {
form.addEventListener('submit', async (e) => {
e.preventDefault();
try {
const response = await fetch(form.action, {
method: 'POST',
body: new FormData(form),
headers: {
'X-CSRFToken':
form.querySelector('[name=csrfmiddlewaretoken]').value
}
});
if (response.ok) {
const notification =
document.getElementById('cartNotification');
notification.classList.add('show');
const cartCount =
document.querySelector('.cart-count');
cartCount.textContent =
parseInt(cartCount.textContent) + 1;
setTimeout(() => {
notification.classList.remove('show');
}, 3000);
}
} catch (error) {
console.error('Error adding item to cart:', error);
}
});
});
</script>
</body>
</html>

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,
initial-scale=1.0">
<title>ECom2 Shop - Welcome</title>
<link
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/a
ll.min.css" rel="stylesheet">
<style>
:root {
--primary-color: #1a237e; /* Dark Indigo */
--secondary-color: #3949ab; /* Indigo */
--accent-color: #ff6f61; /* Coral Red */
--success-color: #81c784; /* Light Green */
--background-color: #e8eaf6; /* Light Lavender */
--card-background: white;
--text-color: #1a237e;
--border-radius: 12px;
--shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
--transition: all 0.3s ease;
}

* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

body {
font-family: 'Segoe UI', system-ui, sans-serif;
background-color: var(--background-color);
color: var(--text-color);
line-height: 1.6;
}

.header {
background: var(--primary-color);
color: white;
padding: 1rem;
position: sticky;
top: 0;
z-index: 100;
box-shadow: var(--shadow);
}

.header-content {
max-width: 1200px;
margin: 0 auto;
display: flex;
justify-content: space-between;
align-items: center;
}

.logo {
font-size: 1.5rem;
font-weight: bold;
display: flex;
align-items: center;
gap: 0.5rem;
}

.hero {
background: linear-gradient(135deg, var(--primary-color),
var(--secondary-color));
color: white;
padding: 4rem 1rem;
text-align: center;
}

.hero h1 {
font-size: 2.5rem;
margin-bottom: 1rem;
}

.hero p {
font-size: 1.2rem;
opacity: 0.9;
max-width: 600px;
margin: 0 auto;
}

.container {
max-width: 1200px;
margin: 0 auto;
padding: 2rem 1rem;
}
.quick-actions {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px,
1fr));
gap: 1.5rem;
margin-top: -3rem;
}

.action-card {
background: var(--card-background);
border-radius: var(--border-radius);
padding: 2rem;
text-align: center;
box-shadow: var(--shadow);
transition: var(--transition);
cursor: pointer;
}

.action-card:hover {
transform: translateY(-5px);
box-shadow: 0 8px 15px rgba(0, 0, 0, 0.1);
}

.action-card i {
font-size: 2.5rem;
color: var(--secondary-color);
margin-bottom: 1rem;
}

.action-card h3 {
margin-bottom: 0.5rem;
color: var(--primary-color);
}

.action-card p {
color: #666;
font-size: 0.9rem;
}

.features {
margin-top: 4rem;
}

.section-title {
text-align: center;
margin-bottom: 2rem;
}

.feature-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px,
1fr));
gap: 2rem;
margin-top: 2rem;
}

.feature-card {
background: var(--card-background);
border-radius: var(--border-radius);
padding: 2rem;
box-shadow: var(--shadow);
transition: var(--transition);
}

.feature-card:hover {
transform: translateY(-3px);
}

.feature-card i {
font-size: 2rem;
color: var(--accent-color);
margin-bottom: 1rem;
}

.stats {
background: linear-gradient(135deg, var(--primary-color),
var(--secondary-color));
color: white;
padding: 4rem 1rem;
margin-top: 4rem;
}

.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px,
1fr));
gap: 2rem;
text-align: center;
}

.stat-item h3 {
font-size: 2.5rem;
margin-bottom: 0.5rem;
}

.footer {
background: var(--primary-color);
color: white;
padding: 2rem 1rem;
margin-top: 4rem;
}

.footer-content {
max-width: 1200px;
margin: 0 auto;
text-align: center;
}

/* New styles for the user menu dropdown */


.user-menu {
position: relative;
display: inline-block;
}

.user-menu i {
font-size: 1.5rem;
cursor: pointer;
}

.dropdown-menu {
display: none;
position: absolute;
right: 0;
background-color: var(--card-background);
min-width: 120px;
box-shadow: var(--shadow);
border-radius: var(--border-radius);
z-index: 1;
}

.dropdown-menu a {
color: var(--text-color);
padding: 12px 16px;
text-decoration: none;
display: block;
border-bottom: 1px solid #f1f1f1;
transition: var(--transition);
}

.dropdown-menu a:last-child {
border-bottom: none;
}

.dropdown-menu a:hover {
background-color: var(--background-color);
color: white;
}

/* Additional styles */
/*.btn-login {*/
/* color: white;*/
/* background-color: var(--accent-color);*/
/* padding: 0.5rem 1rem;*/
/* border-radius: var(--border-radius);*/
/* text-decoration: none;*/
/* transition: var(--transition);*/
/*}*/

/*.btn-login:hover {*/
/* background-color: #ff856e;*/
/*}*/

@media (max-width: 768px) {


.hero h1 {
font-size: 2rem;
}

.quick-actions {
margin-top: -2rem;
}

.stats-grid {
grid-template-columns: 1fr;
}
}
</style>
</head>
<body>
<header class="header">
<div class="header-content">
<div class="logo">
<i class="fas fa-shopping-bag"></i>
ECom2 Shop
</div>
<nav>
<!-- Conditionally display the user menu if the user is
logged in -->
<div th:if="${session.loggedInCustomer != null}"
class="user-menu">
<i class="fas fa-user" id="userIcon"></i>
<div class="dropdown-menu" id="dropdownMenu">
<a href="/accounts/logout">Logout</a>
</div>
</div>
<!-- If the user is not logged in, show a login link -->
<!-- <div th:if="${session.loggedInCustomer == null}">-->
<!-- <a href="/login" class="btn-login">Login</a>-->
<!-- </div>-->
</nav>
</div>
</header>

<section class="hero">
<h1>Welcome to ECom2 Shop</h1>
<p>Discover amazing products with great deals and secure shopping
experience</p>
</section>

<div class="container">
{% comment %}
The quick-actions section with proper card components
{% endcomment %}
<div class="quick-actions">
<div class="action-card"
onclick="window.location.href='http://127.0.0.1:8000/book/recommendat
ions/'">
<i class="fas fa-thumbs-up"></i>
<h3>Recommendations</h3>
<p>Discover products tailored for you</p>
</div>
<div class="action-card"
onclick="window.location.href='http://127.0.0.1:8000/book/item/search
'">
<i class="fas fa-store"></i>
<h3>Browse Products</h3>
<p>Explore our wide range of products</p>
</div>
<div class="action-card"
onclick="window.location.href='http://127.0.0.1:8000/cart'">
<i class="fas fa-shopping-cart"></i>
<h3>Your Cart</h3>
<p>View and manage your shopping cart</p>
</div>
<div class="action-card"
onclick="window.location.href='/order/1'">
<i class="fas fa-box"></i>
<h3>Orders</h3>
<p>Track your orders and view history</p>
</div>
</div>
</div>

<div class="features">
<div class="section-title">
<h2>Why Choose Us</h2>
</div>
<div class="feature-grid">
<div class="feature-card">
<i class="fas fa-shipping-fast"></i>
<h3>Fast Delivery</h3>
<p>Get your orders delivered quickly and safely to
your doorstep</p>
</div>
<div class="feature-card">
<i class="fas fa-shield-alt"></i>
<h3>Secure Shopping</h3>
<p>Shop with confidence with our secure payment
system</p>
</div>
<div class="feature-card">
<i class="fas fa-headset"></i>
<h3>24/7 Support</h3>
<p>Our customer support team is always here to help
you</p>
</div>
</div>
</div>
</div>

<section class="stats">
<div class="container">
<div class="stats-grid">
<div class="stat-item">
<h3>10k+</h3>
<p>Happy Customers</p>
</div>
<div class="stat-item">
<h3>5k+</h3>
<p>Products</p>
</div>
<div class="stat-item">
<h3>99%</h3>
<p>Satisfaction Rate</p>
</div>
<div class="stat-item">
<h3>24/7</h3>
<p>Customer Support</p>
</div>
</div>
</div>
</section>

<footer class="footer">
<div class="footer-content">
<p>&copy; 2024 ECom2 Shop. All rights reserved.</p>
</div>
</footer>

<script>
// Smooth scrolling for anchor links
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();

document.querySelector(this.getAttribute('href')).scrollIntoView({
behavior: 'smooth'
});
});
});

// Hover effect for action cards


document.querySelectorAll('.action-card').forEach(card => {
card.addEventListener('mouseover', function() {
this.style.transform = 'translateY(-8px)';
});
card.addEventListener('mouseout', function() {
this.style.transform = 'translateY(-5px)';
});
});

// Script to handle user menu dropdown


document.addEventListener('DOMContentLoaded', function() {
var userIcon = document.getElementById('userIcon');
var dropdownMenu = document.getElementById('dropdownMenu');

if (userIcon) {
userIcon.addEventListener('click', function(event) {
event.stopPropagation();
dropdownMenu.style.display =
dropdownMenu.style.display === 'block' ? 'none' : 'block';
});

// Close the dropdown if the user clicks outside of it


window.addEventListener('click', function() {
if (dropdownMenu.style.display === 'block') {
dropdownMenu.style.display = 'none';
}
});
}
});
</script>
</body>
</html>

You might also like