add cards and cart

This commit is contained in:
AndriiSyrotenko 2023-11-02 18:14:07 +00:00
parent 0e57411ace
commit da7936bfb2
48 changed files with 1202 additions and 1205 deletions

12
.vscode/settings.json vendored
View File

@ -1,7 +1,7 @@
{
"explorer.fileNesting.enabled": true,
"explorer.fileNesting.patterns": {
"*.cshtml": "${capture}.cshtml, ${capture}.cshtml.cs, ${capture}.cshtml.css",
"*.razor": "${capture}.razor, ${capture}.razor.css,${capture}.razor.cs"
}
{
"explorer.fileNesting.enabled": true,
"explorer.fileNesting.patterns": {
"*.cshtml": "${capture}.cshtml, ${capture}.cshtml.cs, ${capture}.cshtml.css",
"*.razor": "${capture}.razor, ${capture}.razor.css,${capture}.razor.cs"
}
}

View File

@ -13,26 +13,28 @@ public class GlobalUserMiddleware
this._next = next;
}
public async Task InvokeAsync(HttpContext httpContext, AuthenticationService authenticationService, ApiClient apiClient)
public async Task InvokeAsync(HttpContext httpContext, AuthenticationService authenticationService, ApiClient apiClient)
{
try
if (httpContext.Request.Path != "/login")
{
var accessToken = await authenticationService.GetAuthTokenAsync();
if (!string.IsNullOrEmpty(accessToken))
try
{
apiClient.JwtToken = accessToken;
GlobalUser.Roles = authenticationService.GetRolesFromJwtToken(accessToken);
GlobalUser.Id = authenticationService.GetIdFromJwtToken(accessToken);
GlobalUser.Email = authenticationService.GetEmailFromJwtToken(accessToken);
GlobalUser.Phone = authenticationService.GetPhoneFromJwtToken(accessToken);
var accessToken = await authenticationService.GetAuthTokenAsync();
if (!string.IsNullOrEmpty(accessToken))
{
apiClient.JwtToken = accessToken;
GlobalUser.Roles = authenticationService.GetRolesFromJwtToken(accessToken);
GlobalUser.Id = authenticationService.GetIdFromJwtToken(accessToken);
GlobalUser.Email = authenticationService.GetEmailFromJwtToken(accessToken);
GlobalUser.Phone = authenticationService.GetPhoneFromJwtToken(accessToken);
}
}
catch (AuthenticationException ex)
{
httpContext.Response.Cookies.Delete("accessToken");
httpContext.Response.Redirect("/login");
}
}
catch (AuthenticationException ex)
{
httpContext.Response.Cookies.Delete("accessToken");
httpContext.Response.Redirect("");
}
await _next(httpContext);
}
}

View File

@ -1,20 +1,20 @@
namespace ShoppingAssistantWebClient.Web.Models;
public class Product
{
public required string Id {get; set;}
public required string Url {get; set;}
public required string Name {get; set;}
public required string Description {get; set;}
public required double Rating {get; set;}
public required string[] ImagesUrls {get; set;}
public required bool WasOpened {get; set;}
public required string WishlistId {get; set;}
namespace ShoppingAssistantWebClient.Web.Models;
public class Product
{
public required string Id {get; set;}
public required string Url {get; set;}
public required string Name {get; set;}
public required string Description {get; set;}
public required double Rating {get; set;}
public required string[] ImagesUrls {get; set;}
public required bool WasOpened {get; set;}
public required string WishlistId {get; set;}
}

View File

@ -1,12 +1,12 @@
namespace ShoppingAssistantWebClient.Web.Models;
public class Wishlist
{
public required string Id {get; set;}
public required string Name {get; set;}
public required string Type {get; set;}
public required string CreateById {get; set;}
namespace ShoppingAssistantWebClient.Web.Models;
public class Wishlist
{
public required string Id {get; set;}
public required string Name {get; set;}
public required string Type {get; set;}
public required string CreateById {get; set;}
}

View File

@ -0,0 +1,86 @@
@page "/cards"
<div class="card-page">
<div class="head">
<button class="back-button"></button>
<p class="header-text">Gift for Jessica</p>
</div>
<div class="content">
<div class="back-card"></div>
@if (Products != null && Products.Count != 0 && currentProduct != Products.Count && currentProduct >= 0) {
<div class="card">
<div class="slider-container">
<div class="slider">
@foreach (var image in Products[currentProduct].ImagesUrls) {
if (currentImage == image) {
<img src="@image" class="slider-image" @onclick="(() => ChangeImage(image))"/>
}
}
</div>
<div class="dots">
@for (var i = 0; i < Products[currentProduct].ImagesUrls.Length; i++) {
var dotIndex = i;
<div class="dot @(i == currentIndex ? "active-dot" : "")" @onclick="(() => ChangeImageDot(dotIndex))"></div>
}
</div>
</div>
<div class="product-info">
<p class="name">@Products[currentProduct].Name</p>
<p class="description">@Products[currentProduct].Description</p>
<div class="rating-price-row">
<label class="rating">@Products[currentProduct].Rating</label>
@{
int whole = (int)Math.Floor(Products[currentProduct].Rating);
double fractal = Products[currentProduct].Rating - whole;
string price = "N/A";
}
@for(int i = 0; i < 5; i++) {
if(i < whole) {
<img class="star" src="/images/star-cards.png">
continue;
}
if(fractal != 0.0) {
<img class="star" src="/images/half-star.png">
fractal -= fractal;
}
else {
<img class="star" src="/images/empty-star.png">
}
}
<label class="price-label">@price</label>
</div>
</div>
</div>
<div class="buttons-container">
<div class="buttons-row">
<button class="cancel-button" @onclick="(() => LoadNextProduct())"></button>
<button class="return-button" @onclick="(() => LoadPreviousProduct())"></button>
<button class="like-button" @onclick="(() => LoadNextProduct())"></button>
</div>
</div>
}
else {
<style>
.back-card {
display: none;
}
</style>
<div class="card-text">
<label class="bold-text">The cards ended</label>
<label class="more-text">Click <img src="/images/load-more-small.png"/> to see more<br> or <img src="/images/return-small.png"/> to exit</label>
</div>
<div class="buttons-container">
<div class="buttons-row">
<button class="exit-button" @onclick="(() => NavigateToMain())"></button>
<button class="return-button" @onclick="(() => LoadPreviousProduct())"></button>
<button class="more-button" @onclick="(() => LoadMoreProducts())"></button>
</div>
</div>
}
</div>
</div>

View File

@ -0,0 +1,65 @@
using Microsoft.AspNetCore.Components;
using ShoppingAssistantWebClient.Web.Models;
namespace ShoppingAssistantWebClient.Web.Pages;
public partial class Cards
{
private int currentIndex = 0;
private int currentProduct = 0;
private string currentImage;
private static string[] Images = {
"/images/image2.png",
"/images/image1.png",
"/images/return-card.png"
};
public List<Product> Products = new()
{
new Product {Id = "0", Url = "some link", Name = "Belkin USB C to VGA + Charge Adapter - USB C to VGA Cable for MacBook",
Description = "The USB C to VGA + Charge Adapter connects to your laptop or tablet via USB-C port, giving you both a VGA port for video display and a USB-C port for power", Rating = 3.8, ImagesUrls = Images, WasOpened = false, WishlistId = "0"},
new Product {Id = "1", Url = "some link", Name = "Second product",
Description = "Test description", Rating = 4.2, ImagesUrls = Images, WasOpened = false, WishlistId = "0"}
};
protected override void OnInitialized()
{
currentImage = Images[currentIndex];
base.OnInitialized();
}
private void ChangeImage(string image) {
currentIndex = Array.IndexOf(Products[currentProduct].ImagesUrls, image);
currentIndex = (currentIndex + 1) % Products[currentProduct].ImagesUrls.Length;
currentImage = Products[currentProduct].ImagesUrls[currentIndex];
StateHasChanged();
}
private void ChangeImageDot(int index) {
if (index >= 0 && index < Products[currentProduct].ImagesUrls.Length) {
currentIndex = index;
currentImage = Products[currentProduct].ImagesUrls[currentIndex];
StateHasChanged();
}
}
private void LoadNextProduct() {
currentProduct += 1;
StateHasChanged();
}
private void LoadPreviousProduct() {
currentProduct -= 1;
StateHasChanged();
}
private void NavigateToMain() {
}
private void LoadMoreProducts() {
}
}

View File

@ -0,0 +1,244 @@
.card-page {
position: relative;
border: 0.09em solid;
border-color: #0052CC;
border-radius: 0.6em;
height: 100%;
width: 100%;
}
.container {
display: flex;
flex-direction: column;
height: 100%;
}
.content {
padding-top: -52px;
display: flex;
flex-direction: column;
flex-grow: 1;
justify-content: center;
align-items: center;
height: 100%;
position: relative;
}
.head {
display: flex;
justify-content: center;
align-items: center;
}
.header-text {
text-align: center;
font-size: 24px;
color: rgba(0, 82, 204, 0.8);
}
.back-button {
width: 20px;
height: 20px;
background-image: url("images/back-button.png");
background-size: cover;
border: none;
background-color: transparent;
position: absolute;
left: 40px;
}
.back-card,
.card,
.card-text {
width: 19em;
height: 30em;
border-radius: 15px;
position: absolute;
}
.back-card {
transform: rotate(-5deg);
box-shadow: 0 0 10px rgba(0, 82, 204, 1);
z-index: 1;
}
.card,
.card-text {
box-shadow: 0 0 10px rgba(1, 101, 255, 1);
padding: 30px 20px 50px 20px;
z-index: 2;
}
.slider-container {
position: relative;
width: 100%;
height: 220px;
margin: 0 auto;
overflow: hidden;
border-radius: 15px;
}
.slider {
display: flex;
transition: transform 0.3s ease-in-out;
}
.slider-image {
width: 250px;
height: 180px;
object-fit: cover;
}
.dots {
display: flex;
justify-content: center;
margin-top: 15px;
}
.dot {
width: 10px;
height: 10px;
background-color: rgba(234, 234, 234, 1);
border-radius: 50%;
margin: 0 8px;
cursor: pointer;
}
.active-dot {
background-color: rgba(50, 50, 50, 1);
}
.product-info {
flex: 1;
display: flex;
flex-direction: column;
}
.name,
.description {
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
text-overflow: ellipsis;
}
.name {
max-height: 60px;
font-weight: bold;
font-size: 15px;
-webkit-line-clamp: 2;
}
.description {
max-height: 70px;
font-size: 13px;
-webkit-line-clamp: 3;
position: absolute;
top: 300px;
right: 20px;
left: 20px;
}
.star {
margin-right: 5px;
}
.rating {
margin-right: 15px;
}
.rating-price-row {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: auto;
}
.price-label {
margin-left: auto;
font-weight: bold;
}
.buttons-container {
width: 300px;
position: absolute;
margin-top: 640px;
z-index: 3;
}
.buttons-row {
display: flex;
justify-content: space-between;
position: absolute;
bottom: 15px;
left: 20px;
right: 20px;
}
.cancel-button {
width: 30px;
height: 30px;
background-image: url("images/cancel-button.png");
background-size: cover;
border: none;
background-color: transparent;
}
.return-button {
width: 30px;
height: 30px;
background-image: url("images/return-card.png");
background-size: cover;
border: none;
background-color: transparent;
}
.like-button {
width: 30px;
height: 30px;
background-image: url("images/like-button.png");
background-size: cover;
border: none;
background-color: transparent;
}
.exit-button {
width: 30px;
height: 30px;
background-image: url("images/exit.png");
background-size: cover;
border: none;
background-color: transparent;
}
.more-button {
width: 30px;
height: 30px;
background-image: url("images/load-more.png");
background-size: cover;
border: none;
background-color: transparent;
}
.bold-text {
font-size: 24px;
font-weight: bold;
}
.add-text {
font-size: 12px;
}
.exit-text {
font-size: 12px;
}
.card-text {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: left;
}

View File

@ -1,24 +1,37 @@
@page "/cart"
<h1 style="text-align: center; margin-bottom: 50px">Cart</h1>
<div class="container">
@foreach (var product in Products) {
<div class="product-div">
<img class="product-img" src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSe7MHcuWUvuNJsttl3MEVxEayUGVNH4tA2Ha0K4szpgKvH7QYuiaBa_hCzUgW96I6LXqM&usqp=CAU">
<label class="product-description">@product.Description</label>
<div class="button-row">
<img class="star" src="~/assets/star.png">
<label class="rating">@product.Rating</label>
@{
string price = "N/A";
}
<label class="price-label">@price</label>
</div>
<form class="button">
<button class="button-amazon">
<img src="~/assets/amazon.png">
</button>
</form>
</div>
}
</div>
@page "/cart"
<div class="cart">
<div class="head">
<button class="back-button" @onclick="NavigateToMainPage"></button>
<p class="header-text">Cart</p>
</div>
<div class="container">
@foreach (var product in Products) {
<div class="product-div">
<img class="product-img" src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSe7MHcuWUvuNJsttl3MEVxEayUGVNH4tA2Ha0K4szpgKvH7QYuiaBa_hCzUgW96I6LXqM&usqp=CAU">
<label class="product-description">@product.Description</label>
<div class="button-row">
<img class="star" src="/images/star.png">
<label class="rating">@product.Rating</label>
@{
string price = "N/A";
}
<label class="price-label">@price</label>
</div>
<button class="button-amazon">
<img src="/images/amazon.png">
</button>
</div>
}
</div>
</div>
@code
{
[Inject]
private NavigationManager NavigationManager {get; set;}
private void NavigateToMainPage()
{
NavigationManager.NavigateTo("/Cards");
}
}

View File

@ -1,19 +1,51 @@
using Microsoft.AspNetCore.Components;
using ShoppingAssistantWebClient.Web.Models;
namespace ShoppingAssistantWebClient.Web.Pages;
public partial class Cart : ComponentBase
{
public List<Product> Products = new()
{
new Product {Id = "0", Url = "some link", Name = "HDMI", Description = "super mega hdmi cabel", Rating = 3.8, ImagesUrls = new string[] {"link"}, WasOpened = false, WishlistId = "0"},
new Product {Id = "1", Url = "some link", Name = "HDMI", Description = "super mega hdmi cabel", Rating = 3.8, ImagesUrls = new string[] {"link"}, WasOpened = false, WishlistId = "1"},
new Product {Id = "2", Url = "some link", Name = "HDMI", Description = "super mega hdmi cabel", Rating = 3.8, ImagesUrls = new string[] {"link"}, WasOpened = false, WishlistId = "2"}
};
protected override async Task OnInitializedAsync()
{
// Get data from Back-end
}
using Microsoft.AspNetCore.Components;
using ShoppingAssistantWebClient.Web.Models;
namespace ShoppingAssistantWebClient.Web.Pages;
public partial class Cart : ComponentBase
{
public List<Product> Products = new()
{
new Product {Id = "0", Url = "some link", Name = "HDMI", Description = "super mega hdmi cabel", Rating = 3.8, ImagesUrls = new string[] {"link"}, WasOpened = false, WishlistId = "0"},
new Product {Id = "1", Url = "some link", Name = "HDMI", Description = "super mega hdmi cabel", Rating = 3.8, ImagesUrls = new string[] {"link"}, WasOpened = false, WishlistId = "1"},
new Product {Id = "2", Url = "some link", Name = "HDMI", Description = "super mega hdmi cabel", Rating = 3.8, ImagesUrls = new string[] {"link"}, WasOpened = false, WishlistId = "2"},
new Product {Id = "1", Url = "some link", Name = "HDMI", Description = "super mega hdmi cabel", Rating = 3.8, ImagesUrls = new string[] {"link"}, WasOpened = false, WishlistId = "1"},
new Product {Id = "1", Url = "some link", Name = "HDMI", Description = "super mega hdmi cabel", Rating = 3.8, ImagesUrls = new string[] {"link"}, WasOpened = false, WishlistId = "1"},
new Product {Id = "1", Url = "some link", Name = "HDMI", Description = "super mega hdmi cabel", Rating = 3.8, ImagesUrls = new string[] {"link"}, WasOpened = false, WishlistId = "1"},
new Product {Id = "1", Url = "some link", Name = "HDMI", Description = "super mega hdmi cabel", Rating = 3.8, ImagesUrls = new string[] {"link"}, WasOpened = false, WishlistId = "1"},
new Product {Id = "1", Url = "some link", Name = "HDMI", Description = "super mega hdmi cabel", Rating = 3.8, ImagesUrls = new string[] {"link"}, WasOpened = false, WishlistId = "1"},
new Product {Id = "1", Url = "some link", Name = "HDMI", Description = "super mega hdmi cabel", Rating = 3.8, ImagesUrls = new string[] {"link"}, WasOpened = false, WishlistId = "1"},
new Product {Id = "1", Url = "some link", Name = "HDMI", Description = "super mega hdmi cabel", Rating = 3.8, ImagesUrls = new string[] {"link"}, WasOpened = false, WishlistId = "1"},
new Product {Id = "1", Url = "some link", Name = "HDMI", Description = "super mega hdmi cabel", Rating = 3.8, ImagesUrls = new string[] {"link"}, WasOpened = false, WishlistId = "1"},
new Product {Id = "1", Url = "some link", Name = "HDMI", Description = "super mega hdmi cabel", Rating = 3.8, ImagesUrls = new string[] {"link"}, WasOpened = false, WishlistId = "1"},
new Product {Id = "1", Url = "some link", Name = "HDMI", Description = "super mega hdmi cabel", Rating = 3.8, ImagesUrls = new string[] {"link"}, WasOpened = false, WishlistId = "1"},
new Product {Id = "1", Url = "some link", Name = "HDMI", Description = "super mega hdmi cabel", Rating = 3.8, ImagesUrls = new string[] {"link"}, WasOpened = false, WishlistId = "1"},
new Product {Id = "1", Url = "some link", Name = "HDMI", Description = "super mega hdmi cabel", Rating = 3.8, ImagesUrls = new string[] {"link"}, WasOpened = false, WishlistId = "1"},
new Product {Id = "1", Url = "some link", Name = "HDMI", Description = "super mega hdmi cabel", Rating = 3.8, ImagesUrls = new string[] {"link"}, WasOpened = false, WishlistId = "1"},
new Product {Id = "1", Url = "some link", Name = "HDMI", Description = "super mega hdmi cabel", Rating = 3.8, ImagesUrls = new string[] {"link"}, WasOpened = false, WishlistId = "1"},
new Product {Id = "1", Url = "some link", Name = "HDMI", Description = "super mega hdmi cabel", Rating = 3.8, ImagesUrls = new string[] {"link"}, WasOpened = false, WishlistId = "1"},
new Product {Id = "1", Url = "some link", Name = "HDMI", Description = "super mega hdmi cabel", Rating = 3.8, ImagesUrls = new string[] {"link"}, WasOpened = false, WishlistId = "1"},
new Product {Id = "1", Url = "some link", Name = "HDMI", Description = "super mega hdmi cabel", Rating = 3.8, ImagesUrls = new string[] {"link"}, WasOpened = false, WishlistId = "1"},
new Product {Id = "1", Url = "some link", Name = "HDMI", Description = "super mega hdmi cabel", Rating = 3.8, ImagesUrls = new string[] {"link"}, WasOpened = false, WishlistId = "1"},
new Product {Id = "1", Url = "some link", Name = "HDMI", Description = "super mega hdmi cabel", Rating = 3.8, ImagesUrls = new string[] {"link"}, WasOpened = false, WishlistId = "1"},
new Product {Id = "1", Url = "some link", Name = "HDMI", Description = "super mega hdmi cabel", Rating = 3.8, ImagesUrls = new string[] {"link"}, WasOpened = false, WishlistId = "1"},
new Product {Id = "1", Url = "some link", Name = "HDMI", Description = "super mega hdmi cabel", Rating = 3.8, ImagesUrls = new string[] {"link"}, WasOpened = false, WishlistId = "1"},
new Product {Id = "1", Url = "some link", Name = "HDMI", Description = "super mega hdmi cabel", Rating = 3.8, ImagesUrls = new string[] {"link"}, WasOpened = false, WishlistId = "1"},
new Product {Id = "1", Url = "some link", Name = "HDMI", Description = "super mega hdmi cabel", Rating = 3.8, ImagesUrls = new string[] {"link"}, WasOpened = false, WishlistId = "1"},
new Product {Id = "1", Url = "some link", Name = "HDMI", Description = "super mega hdmi cabel", Rating = 3.8, ImagesUrls = new string[] {"link"}, WasOpened = false, WishlistId = "1"},
new Product {Id = "1", Url = "some link", Name = "HDMI", Description = "super mega hdmi cabel", Rating = 3.8, ImagesUrls = new string[] {"link"}, WasOpened = false, WishlistId = "1"},
new Product {Id = "1", Url = "some link", Name = "HDMI", Description = "super mega hdmi cabel", Rating = 3.8, ImagesUrls = new string[] {"link"}, WasOpened = false, WishlistId = "1"},
new Product {Id = "1", Url = "some link", Name = "HDMI", Description = "super mega hdmi cabel", Rating = 3.8, ImagesUrls = new string[] {"link"}, WasOpened = false, WishlistId = "1"},
new Product {Id = "1", Url = "some link", Name = "HDMI", Description = "super mega hdmi cabel", Rating = 3.8, ImagesUrls = new string[] {"link"}, WasOpened = false, WishlistId = "1"},
new Product {Id = "1", Url = "some link", Name = "HDMI", Description = "super mega hdmi cabel", Rating = 3.8, ImagesUrls = new string[] {"link"}, WasOpened = false, WishlistId = "1"},
new Product {Id = "1", Url = "some link", Name = "HDMI", Description = "super mega hdmi cabel", Rating = 3.8, ImagesUrls = new string[] {"link"}, WasOpened = false, WishlistId = "1"},
new Product {Id = "1", Url = "some link", Name = "HDMI", Description = "super mega hdmi cabel", Rating = 3.8, ImagesUrls = new string[] {"link"}, WasOpened = false, WishlistId = "1"},
new Product {Id = "1", Url = "some link", Name = "HDMI", Description = "super mega hdmi cabel", Rating = 3.8, ImagesUrls = new string[] {"link"}, WasOpened = false, WishlistId = "1"},
};
protected override async Task OnInitializedAsync()
{
// Get data from Back-end
}
}

View File

@ -1,74 +1,121 @@
.container {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.product-div {
height: 310px;
width: 200px;
border-radius: 10px;
box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.1);
position: relative;
padding: 0 10px 0 10px;
margin: 30px;
}
.product-img {
height: 130px;
width: 100%;
align-self: center;
display: block;
margin: 10px;
}
.product-description {
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.button-amazon {
display: flex;
justify-content: center;
align-items: center;
background-color: #009FFF;
border: none;
border-radius: 10px;
position: absolute;
width: 90%;
height: 40px;
bottom: 10px;
}
.star {
position: absolute;
bottom: 60px;
}
.rating {
position: absolute;
bottom: 60px;
left: 35px;
height: 16px;
display: flex;
justify-content: center;
align-items: center;
}
.button-row {
display: flex;
}
.price-label {
position: absolute;
right: 10px;
font-weight: bold;
font-size: larger;
height: 16px;
bottom: 60px;
display: flex;
justify-content: center;
align-items: center;
.cart {
border-radius: 10px;
border: 1px solid #0052CC;
position: fixed;
left: 20px;
right: 20px;
top: 20px;
bottom: 20px;
padding: 20px;
overflow: auto;
-ms-overflow-style: none;
scrollbar-width: none;
}
.cart::-webkit-scrollbar {
display: none;
}
.head {
display: flex;
justify-content: center;
align-items: center;
font-size: large;
}
.header-text {
text-align: center;
font-size: 12;
color: rgba(0, 82, 204, 0.8);
}
.back-button {
width: 15px;
height: 15px;
background-image: url("images/back-button.png");
background-size: cover;
border: none;
background-color: transparent;
position: absolute;
left: 20px;
}
.container {
display: flex;
flex-wrap: wrap;
justify-content: center;
max-width: 720px;
overflow: auto;
}
.product-div {
height: 190px;
width: 130px;
border-radius: 10px;
box-shadow: 1px 1px 10px rgba(0, 0, 0, 0.3);
position: relative;
padding: 0 10px 0 10px;
margin: 15px 15px 15px 15px;
}
.product-img {
height: 70px;
width: 100%;
align-self: center;
display: block;
margin: 10px;
}
.product-description {
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
font-size: 12px;
}
.button-amazon {
display: flex;
justify-content: center;
align-items: center;
background-color: #009FFF;
border: none;
border-radius: 10px;
position: absolute;
width: 109px;
height: 27px;
bottom: 10px;
}
.star {
position: absolute;
bottom: 45px;
}
.rating {
position: absolute;
bottom: 45px;
left: 26px;
height: 9px;
width: 9px;
display: flex;
justify-content: center;
align-items: center;
font-size: 12px;
}
.button-row {
display: flex;
}
.price-label {
position: absolute;
right: 10px;
font-weight: bold;
font-size: 14px;
height: 16px;
bottom: 45px;
display: flex;
justify-content: center;
align-items: center;
}

View File

@ -1,227 +0,0 @@
@page "/chat/1"
@model ShoppingAssistantWebClient.Web.Pages.ChatModel
@{
ViewData["Title"] = "Gift for Jessica";
}
<div class="container-fluid">
<div class="left_frame" id="leftFrame">
<div class="logo">
<img src="/images/logo.png" alt="Logo site">
<span class="logo_name">CARTAID</span>
</div>
<div class="menu">
<div class="elements_wishlisht">
<div class="close_menu">
<span >Wishlists</span>
<a class="button_close_menu" >
<span></span>
<span></span>
<span></span>
</a>
</div>
<div class="add_chat">
<a href="/">
<span >Add chat +</span>
</a>
</div>
<div class="wishlist_names">
<section>
<span id ="wishlist_id_1" class="wishlist_name">Gift for Jessica</span>
</section>
<section>
<span id ="wishlist_id_2" class="wishlist_name">Secret Santa</span>
</section>
<section>
<span id ="wishlist_id_3" class="wishlist_name">Phone charger</span>
</section>
<section>
<span class="wishlist_name">Phone</span>
</section>
<section>
<span class="wishlist_name">Printer</span>
<section>
<span class="wishlist_name">Books</span>
</section>
</div>
</div>
<div class="line"></div>
<div class="elements">
<div class="info_user">
<img src="/images/avatar.jpg" alt="Avatar user">
<span class="user_name">Username</span>
</div>
</div>
</div>
</div>
<div class="right_frame" id="rightFrame">
<div class="open_menu">
<a class="button_open_menu" >
<span></span>
<span></span>
<span></span>
</a>
</div>
<div class="chat_frame">
<div class="new_chat">
<div class="title_one_frame">Gift for Jessica</div>
<ul class="chat_box">
<li class="chat_outgoing">
<p>Give me product recommendation. Ask me questions if you need more directions. I am looking for: hub for my macbook to connect external monitors</p>
</li>
<li class=" chat_incoming">
<p>Sure! I can help you with that. I will ask you some leading questions. This is the first:
<br>
How many external monitors do you want to connect to your MacBook?</p>
</li>
<li class="chat_outgoing">
<p>7</p>
</li>
<li class=" chat_incoming">
<p>Thank you. Here is the next question:
<br>
What type of external monitors do you have? (e.g., HDMI, DisplayPort, VGA)</p>
</li>
</ul>
<div class="chat_input">
<input type="text" id="chatInput" placeholder="Describe what you are looking for....">
<a class="button_sende">
<img src="/images/send.png" alt="Send message">
</a>
</div>
</div>
</div>
</div>
<script>
const leftFrame = document.getElementById("leftFrame");
const rightFrame = document.getElementById("rightFrame");
const openMenuButton = document.querySelector(".button_open_menu");
const closeMenuButton = document.querySelector(".button_close_menu");
const choose_gift = document.getElementById("choose_gift");
const choose_product = document.getElementById("choose_product");
const switchGift = document.querySelector(".switch_gift");
const switchProduct = document.querySelector(".switch_product");
const isLeftFrameOpen = localStorage.getItem('leftFrameOpen');
if (isLeftFrameOpen) {
requestAnimationFrame(() => {
leftFrame.style.transform = "translateX(0%)";
rightFrame.style.transform = "translateX(calc(30% - 40px))";
rightFrame.style.width = "calc(80% - 60px)";
});
openMenuButton.style.visibility = "hidden";
closeMenuButton.style.visibility = "visible";
} else {
requestAnimationFrame(() => {
leftFrame.style.transform = "translateX(-100%)";
rightFrame.style.transform = "translateX(0%)";
rightFrame.style.width = "calc(100% - 40px)";
});
closeMenuButton.style.visibility = "hidden";
openMenuButton.style.visibility = "visible";
}
openMenuButton.addEventListener("click", function () {
requestAnimationFrame(() => {
leftFrame.style.transform = "translateX(0%)";
rightFrame.style.transform = "translateX(calc(30% - 40px))";
rightFrame.style.width = "calc(80% - 60px)";
});
openMenuButton.style.visibility = "hidden";
closeMenuButton.style.visibility = "visible";
});
closeMenuButton.addEventListener("click", function () {
requestAnimationFrame(() => {
leftFrame.style.transform = "translateX(-100%)";
rightFrame.style.transform = "translateX(0%)";
rightFrame.style.width = "calc(100% - 40px)";
});
closeMenuButton.style.visibility = "hidden";
openMenuButton.style.visibility = "visible";
});
switchGift.addEventListener("click", function () {
requestAnimationFrame(() => {
choose_gift.style.backgroundColor = "#0052CC";
choose_product.style.backgroundColor = "transparent";
switchGift.style.color = "white";
switchProduct.style.color = "#202124";
});
});
switchProduct.addEventListener("click", function () {
requestAnimationFrame(() => {
choose_product.style.backgroundColor = "#0052CC";
choose_gift.style.backgroundColor = "transparent";
switchProduct.style.color = "white";
switchGift.style.color = "#202124";
});
});
const new_chat = document.querySelector(".button_add_chat");
new_chat.addEventListener("click", function () {
alert(3)
});
</script>

View File

@ -1,21 +0,0 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using ShoppingAssistantWebClient.Web.Network;
namespace ShoppingAssistantWebClient.Web.Pages;
public class ChatModel : PageModel
{
private readonly ILogger<ChatModel> _logger;
private readonly AuthenticationService _authenticationService;
public ChatModel(ILogger<ChatModel> logger, AuthenticationService authenticationService)
{
_authenticationService = authenticationService;
_logger = logger;
}
public void OnGet()
{
}
}

View File

@ -1,14 +1,14 @@
using Microsoft.AspNetCore.Components;
namespace ShoppingAssistantWebClient.Web.Pages;
public partial class Chat : ComponentBase
{
[Inject]
public ILogger<Chat> Logger { get; set; }
protected override async Task OnInitializedAsync()
{
// Get data from Back-end
}
}
using Microsoft.AspNetCore.Components;
namespace ShoppingAssistantWebClient.Web.Pages;
public partial class Chat : ComponentBase
{
[Inject]
public ILogger<Chat> Logger { get; set; }
protected override async Task OnInitializedAsync()
{
// Get data from Back-end
}
}

View File

@ -1,361 +1,361 @@
html {
font-family: 'Nunito';
padding-top: 20px;
padding-bottom: 20px;
}
.menu {
position: relative;
width: 100%;
height: 100%;
border: 1.5px solid;
border-color: #0052CC;
border-radius: 10px;
padding-top: 16px;
padding-bottom: 16px;
}
.logo {
display: flex;
align-items: center;
padding-bottom: 15PX;
}
.logo_name {
padding-top: 10px;
padding-left: 3px;
font-size: 17px;
justify-content: center;
/* Горизонтальное центрирование */
align-items: center;
letter-spacing: 0.5px;
font-weight: 600;
}
.logo img {
float: left;
width: 52px;
height: 52px;
}
.left_frame {
padding-left: 20px;
position: absolute;
height: calc(100% - 105px);
left: 0;
width: 20%;
transition: 1s;
}
.wishlist_name {
font-size: 15px;
margin-top: 7px;
margin-bottom: 7px;
color: black;
cursor: pointer;
}
.elements {
padding-left: 12px;
padding-right: 12px;
}
.elements_wishlisht{
overflow-y: scroll;
padding-left: 12px;
padding-right: 12px;
height: 90%;
}
.elements_wishlisht::-webkit-scrollbar {
visibility: hidden;
}
.close_menu {
position: relative;
background-color: #EAEAEA;
border-radius: 10px;
color: #4E4E4E;
font-size: 16px;
width: 90%;
height: 40px;
padding: 7px 9px;
}
.add_chat {
display: flex;
align-items: center;
justify-content: center;
margin-top: 15px;
margin-bottom: 5px;
background-color: #EAEAEA;
border-radius: 10px;
font-size: 16px;
width: 100px;
height: 40px;
cursor: pointer;
}
.add_chat a{
border-radius: 10px;
padding: 7px 9px;
text-decoration: none;
color: #4E4E4E;
}
.info_user {
background-color: white;
position:absolute;
bottom: 0;
padding-bottom: 10px;
padding-top: 10px;
}
.user_name {
font-size: 16px;
padding-left: 7px;
}
.info_user img {
height: 40px;
width: 40px;
border-radius: 50%;
}
.line {
position: absolute;
bottom: 60px;
width: 100%;
border-bottom: 1px solid #4b7bc4;
}
.button_close_menu{
width: 23px;
height: 23px;
position: absolute;
right: 20px;
cursor: pointer;
}
.button_close_menu span {
width: 20px;
height: 1.5px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: #4E4E4E;
}
.button_close_menu span:nth-of-type(2) {
top: calc(50% - 5px);
}
.button_close_menu span:nth-of-type(3) {
top: calc(50% + 5px);
}
.right_frame {
position: absolute;
border: 1.5px solid;
border-color: #0052CC;
border-radius: 10px;
left: 20px;
height: calc(100% - 40px);
width: calc(100% - 40px);
transition: 1s;
}
.button_open_menu{
z-index: 2;
width: 23px;
height: 23px;
position: absolute;
top: 25px;
left: 25px;
cursor: pointer;
}
.button_open_menu span {
width: 20px;
height: 1.5px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: #4E4E4E;
}
.button_open_menu span:nth-of-type(2) {
top: calc(50% - 5px);
}
.button_open_menu span:nth-of-type(3) {
top: calc(50% + 5px);
}
.title_one_frame{
padding-top: 20px ;
color: #0052CC;
font-size: 17px;
text-align: center;
}
.title_two_frame{
padding-top: 60px ;
padding-bottom: 40px ;
color: black;
font-size: 40px;
text-align: center;
font-weight: 600;
}
.title_three_frame{
padding-top: 60px ;
padding-bottom: 40px ;
color: #202124;
font-size: 20px;
text-align: center;
font-weight: 400;
}
.topic {
font-size: 18px;
text-align: center;
line-height: 35px;
color: #009FFF;
width: 250px;
margin: 0 auto;
}
.topic div{
margin-top: 20px;
border: 1.5px solid;
border-color: #009FFF;
border-radius: 10px;
justify-content: center;
align-items: center;
cursor: pointer;
}
.topic div a{
color: #009FFF;
text-decoration:none;
}
.switch{
height: 45px;
width: 350px;
margin: 0 auto;
border: 1.5px solid;
border-color: #EAEAEA;
border-radius: 10px;
text-align: center;
position: relative;
}
.switch_product{
position: absolute;
background-color: #0052CC;
border-radius: 10px;
margin: 5px;
width: calc(50% - 10px);
height: calc(100% - 10px);
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: 0.8s;
color: white;
}
.switch_gift{
right: 0;
position: absolute;
border-radius: 10px;
margin: 5px;
width: calc(50% - 10px);
height: calc(100% - 10px);
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: 0.8s;
color: #202124;
}
.chat_input{
position: absolute;
margin-left: 25%;
margin-bottom: 20px;
width: 50%;
border-radius: 10px;
bottom: 0;
}
.chat_input input{
font-size: 17px;
width: 100%;
position: relative;
color: #4E4E4E;
background-color: #EAEAEA;
border-radius: 10px;
border: none;
padding: 10px 20px;
outline:none;
}
.button_sende{
margin-top: 14px;
margin-right: 20px;
cursor: pointer;
height: calc(100% - 28px);
width: 2.8%;
position: absolute;
right: 0;
}
.button_sende img{
height: 100%;
width: 100%;
position: absolute;
}
.new_chat{
position: absolute;
overflow-y: scroll;
height: 100%;
width: 100%;
}
.new_chat::-webkit-scrollbar {
visibility: hidden;
}
.chat_box{
border-radius: 10px;
position: absolute;
margin-left: 25%;
margin-top: 35px;
width: 50%;
list-style: none;
padding:0;
}
.chat_outgoing{
display: flex;
}
.chat_incoming{
display: flex;
}
.chat_box .chat_outgoing p {
margin-left: auto;
background-color: #009FFF;
border-radius: 10px;
color: white;
padding: 10px;
max-width: 60%;
}
.chat_box .chat_incoming p {
background-color: #EAEAEA;
border-radius: 10px;
color: black;
padding: 10px;
width: 60%;
margin-bottom: 20px ;
margin-top: 20px ;
html {
font-family: 'Nunito';
padding-top: 20px;
padding-bottom: 20px;
}
.menu {
position: relative;
width: 100%;
height: 100%;
border: 1.5px solid;
border-color: #0052CC;
border-radius: 10px;
padding-top: 16px;
padding-bottom: 16px;
}
.logo {
display: flex;
align-items: center;
padding-bottom: 15PX;
}
.logo_name {
padding-top: 10px;
padding-left: 3px;
font-size: 17px;
justify-content: center;
/* Горизонтальное центрирование */
align-items: center;
letter-spacing: 0.5px;
font-weight: 600;
}
.logo img {
float: left;
width: 52px;
height: 52px;
}
.left_frame {
padding-left: 20px;
position: absolute;
height: calc(100% - 105px);
left: 0;
width: 20%;
transition: 1s;
}
.wishlist_name {
font-size: 15px;
margin-top: 7px;
margin-bottom: 7px;
color: black;
cursor: pointer;
}
.elements {
padding-left: 12px;
padding-right: 12px;
}
.elements_wishlisht{
overflow-y: scroll;
padding-left: 12px;
padding-right: 12px;
height: 90%;
}
.elements_wishlisht::-webkit-scrollbar {
visibility: hidden;
}
.close_menu {
position: relative;
background-color: #EAEAEA;
border-radius: 10px;
color: #4E4E4E;
font-size: 16px;
width: 90%;
height: 40px;
padding: 7px 9px;
}
.add_chat {
display: flex;
align-items: center;
justify-content: center;
margin-top: 15px;
margin-bottom: 5px;
background-color: #EAEAEA;
border-radius: 10px;
font-size: 16px;
width: 100px;
height: 40px;
cursor: pointer;
}
.add_chat a{
border-radius: 10px;
padding: 7px 9px;
text-decoration: none;
color: #4E4E4E;
}
.info_user {
background-color: white;
position:absolute;
bottom: 0;
padding-bottom: 10px;
padding-top: 10px;
}
.user_name {
font-size: 16px;
padding-left: 7px;
}
.info_user img {
height: 40px;
width: 40px;
border-radius: 50%;
}
.line {
position: absolute;
bottom: 60px;
width: 100%;
border-bottom: 1px solid #4b7bc4;
}
.button_close_menu{
width: 23px;
height: 23px;
position: absolute;
right: 20px;
cursor: pointer;
}
.button_close_menu span {
width: 20px;
height: 1.5px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: #4E4E4E;
}
.button_close_menu span:nth-of-type(2) {
top: calc(50% - 5px);
}
.button_close_menu span:nth-of-type(3) {
top: calc(50% + 5px);
}
.right_frame {
position: absolute;
border: 1.5px solid;
border-color: #0052CC;
border-radius: 10px;
left: 20px;
height: calc(100% - 40px);
width: calc(100% - 40px);
transition: 1s;
}
.button_open_menu{
z-index: 2;
width: 23px;
height: 23px;
position: absolute;
top: 25px;
left: 25px;
cursor: pointer;
}
.button_open_menu span {
width: 20px;
height: 1.5px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: #4E4E4E;
}
.button_open_menu span:nth-of-type(2) {
top: calc(50% - 5px);
}
.button_open_menu span:nth-of-type(3) {
top: calc(50% + 5px);
}
.title_one_frame{
padding-top: 20px ;
color: #0052CC;
font-size: 17px;
text-align: center;
}
.title_two_frame{
padding-top: 60px ;
padding-bottom: 40px ;
color: black;
font-size: 40px;
text-align: center;
font-weight: 600;
}
.title_three_frame{
padding-top: 60px ;
padding-bottom: 40px ;
color: #202124;
font-size: 20px;
text-align: center;
font-weight: 400;
}
.topic {
font-size: 18px;
text-align: center;
line-height: 35px;
color: #009FFF;
width: 250px;
margin: 0 auto;
}
.topic div{
margin-top: 20px;
border: 1.5px solid;
border-color: #009FFF;
border-radius: 10px;
justify-content: center;
align-items: center;
cursor: pointer;
}
.topic div a{
color: #009FFF;
text-decoration:none;
}
.switch{
height: 45px;
width: 350px;
margin: 0 auto;
border: 1.5px solid;
border-color: #EAEAEA;
border-radius: 10px;
text-align: center;
position: relative;
}
.switch_product{
position: absolute;
background-color: #0052CC;
border-radius: 10px;
margin: 5px;
width: calc(50% - 10px);
height: calc(100% - 10px);
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: 0.8s;
color: white;
}
.switch_gift{
right: 0;
position: absolute;
border-radius: 10px;
margin: 5px;
width: calc(50% - 10px);
height: calc(100% - 10px);
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: 0.8s;
color: #202124;
}
.chat_input{
position: absolute;
margin-left: 25%;
margin-bottom: 20px;
width: 50%;
border-radius: 10px;
bottom: 0;
}
.chat_input input{
font-size: 17px;
width: 100%;
position: relative;
color: #4E4E4E;
background-color: #EAEAEA;
border-radius: 10px;
border: none;
padding: 10px 20px;
outline:none;
}
.button_sende{
margin-top: 14px;
margin-right: 20px;
cursor: pointer;
height: calc(100% - 28px);
width: 2.8%;
position: absolute;
right: 0;
}
.button_sende img{
height: 100%;
width: 100%;
position: absolute;
}
.new_chat{
position: absolute;
overflow-y: scroll;
height: 100%;
width: 100%;
}
.new_chat::-webkit-scrollbar {
visibility: hidden;
}
.chat_box{
border-radius: 10px;
position: absolute;
margin-left: 25%;
margin-top: 35px;
width: 50%;
list-style: none;
padding:0;
}
.chat_outgoing{
display: flex;
}
.chat_incoming{
display: flex;
}
.chat_box .chat_outgoing p {
margin-left: auto;
background-color: #009FFF;
border-radius: 10px;
color: white;
padding: 10px;
max-width: 60%;
}
.chat_box .chat_incoming p {
background-color: #EAEAEA;
border-radius: 10px;
color: black;
padding: 10px;
width: 60%;
margin-bottom: 20px ;
margin-top: 20px ;
}

View File

@ -1,42 +0,0 @@
@page
@model ShoppingAssistantWebClient.Web.Pages.ErrorModel
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>Error</title>
<link href="~/css/bootstrap/bootstrap.min.css" rel="stylesheet" />
<link href="~/css/site.css" rel="stylesheet" asp-append-version="true" />
</head>
<body>
<div class="main">
<div class="content px-4">
<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>
@if (Model.ShowRequestId)
{
<p>
<strong>Request ID:</strong> <code>@Model.RequestId</code>
</p>
}
<h3>Development Mode</h3>
<p>
Swapping to the <strong>Development</strong> environment displays detailed information about the error that occurred.
</p>
<p>
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
It can result in displaying sensitive information from exceptions to end users.
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
and restarting the app.
</p>
</div>
</div>
</body>
</html>

View File

@ -1,26 +0,0 @@
using System.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace ShoppingAssistantWebClient.Web.Pages;
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
[IgnoreAntiforgeryToken]
public class ErrorModel : PageModel
{
public string? RequestId { get; set; }
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
private readonly ILogger<ErrorModel> _logger;
public ErrorModel(ILogger<ErrorModel> logger)
{
_logger = logger;
}
public void OnGet()
{
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
}
}

View File

@ -0,0 +1,8 @@
@page "/login"
@model ShoppingAssistantWebClient.Web.Pages.LoginModel
<h1>Login</h1>
@{
}

View File

@ -0,0 +1,12 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace ShoppingAssistantWebClient.Web.Pages
{
public class LoginModel : PageModel
{
public void OnGet()
{
}
}
}

View File

@ -1,75 +0,0 @@
@page
@model ShoppingAssistantWebClient.Web.Pages.WishlistModel
@{
//Layout = null;
}
<style>
.table-container {
width: 95%;
height: 95%;
display: flex;
justify-content: center;
align-items: center;
margin: auto;
}
.styled-table {
border-collapse: collapse;
width: 100%;
max-width: 100%;
}
.styled-table th {
border-bottom: 1px solid #ddd;
text-align: center;
font-size: larger;
background-color: rgba(0, 159, 255, 0.1);
}
.styled-table td {
border-bottom: 5px solid #FFF;
border-top: 5px solid #FFF;
text-align: center;
font-size: large;
padding: 20px;
background-color: rgba(248, 248, 255, 1);
}
</style>
<h1 style="text-align: center; margin-bottom: 50px">My Wishlist</h1>
<div class="table-container">
@if(!(Model.wishlist is null))
{
<table class="styled-table">
<thead>
<tr>
<th> </th>
<th style="text-align: left;">Chat name</th>
<th>Type</th>
<th>CreatedById</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.wishlist)
{
<tr>
<form method="post" asp-page-handler="Delete" asp-route-id="@item.Id">
<td><input type="image" src="~/assets/x-button.png"></td>
</form>
<td style="text-align: left">@Html.DisplayFor(modelItem => item.Name)</td>
<td>@Html.DisplayFor(modelItem => item.Type)</td>
<td>@Html.DisplayFor(modelItem => item.CreateById)</td>
<form method="post" asp-page="Wishlist">
<td><input type="image" src="~/assets/shopping-cart.png" asp-page-handler="MoveToChat"></td>
</form>
</tr>
}
</tbody>
</table>
}
else
{
<h3>You don't have a wishlist</h3>
}
</div>

View File

@ -1,28 +0,0 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using ShoppingAssistantWebClient.Web.Models;
namespace ShoppingAssistantWebClient.Web.Pages
{
public class WishlistModel : PageModel
{
public List<Models.Wishlist> wishlist = new List<Models.Wishlist>{
new Models.Wishlist {Id = "0", Name = "Chat1", Type="product", CreateById="0"},
new Models.Wishlist {Id = "1", Name = "Chat2", Type="gift", CreateById="1"},
new Models.Wishlist {Id = "2", Name = "Chat3", Type="product", CreateById="2"}
};
public void OnGet()
{
}
public void OnPostDelete(string id) {
var item = wishlist.FirstOrDefault(wishlist => wishlist.Id == id);
wishlist.RemoveAt(Int32.Parse(id));
}
public IActionResult OnPostMoveToChat() {
return RedirectToPage("Index");
}
}
}

View File

@ -1,42 +0,0 @@
@page "/wishlists"
<h1 style="text-align: center; margin-bottom: 50px">My Wishlist</h1>
<div class="table-container">
@if(WishlistList != null)
{
<table class="styled-table">
<thead>
<tr>
<th> </th>
<th style="text-align: left;">Chat name</th>
<th>Type</th>
<th>CreatedById</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in WishlistList)
{
<tr>
<form method="post" asp-page-handler="Delete" asp-route-id="@item.Id">
<td><input type="image" src="~/assets/x-button.png"></td>
</form>
<td style="text-align: left">@item.Name</td>
<td>@item.Type</td>
<td>@item.CreateById</td>
<form method="post" asp-page="Wishlist">
<td><input type="image" src="~/assets/shopping-cart.png" asp-page-handler="MoveToChat"></td>
</form>
</tr>
}
</tbody>
</table>
}
else
{
<h3>You don't have a wishlist</h3>
}
</div>

View File

@ -1,14 +0,0 @@
using Microsoft.AspNetCore.Components;
using ShoppingAssistantWebClient.Web.Models;
namespace ShoppingAssistantWebClient.Web.Pages;
public partial class Wishlists : ComponentBase
{
public List<Wishlist> WishlistList = new()
{
new Wishlist {Id = "0", Name = "Chat1", Type="product", CreateById="0"},
new Wishlist {Id = "1", Name = "Chat2", Type="gift", CreateById="1"},
new Wishlist {Id = "2", Name = "Chat3", Type="product", CreateById="2"}
};
}

View File

@ -1,28 +0,0 @@
.table-container {
width: 95%;
height: 95%;
display: flex;
justify-content: center;
align-items: center;
margin: auto;
}
.styled-table {
border-collapse: collapse;
width: 100%;
max-width: 100%;
}
.styled-table th {
border-bottom: 1px solid #ddd;
text-align: center;
font-size: larger;
background-color: rgba(0, 159, 255, 0.1);
}
.styled-table td {
border-bottom: 5px solid #FFF;
border-top: 5px solid #FFF;
text-align: center;
font-size: large;
padding: 20px;
background-color: rgba(248, 248, 255, 1);
}

View File

@ -28,6 +28,6 @@ app.UseRouting();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
// app.ConfigureGlobalUserMiddleware();
app.ConfigureGlobalUserMiddleware();
app.Run();

View File

@ -1,15 +1,12 @@
@inherits LayoutComponentBase
@using ShoppingAssistantWebClient.Web.Pages
<PageTitle>ShoppingAssistantWebClient.Web</PageTitle>
<div class="page">
<div class="sidebar-menu">
<NavMenu />
<NavMenu/>
</div>
<!--
<main>
<article class="content px-4">
@Body
</article>
</main>-->
</div>
<div class="right-frame">
@Body
</div>
</div>

View File

@ -1,73 +1,26 @@
.page {
position: relative;
width: 100%;
height: 100vh;
border: 1.5% solid;
border-color: #edf106;
padding: 1.25em;
}
.sidebar-menu {
position: relative;
position: absolute;
width: 20em;
height: 100%;
top: 1.25em;
bottom: 1.25em;
margin-right: 1.5em;
transition: 1s;
border: 1.5% solid;
border-color: #f10606;
}
.top-row {
background-color: #f7f7f7;
border-bottom: 1px solid #d6d5d5;
justify-content: flex-end;
height: 3.5rem;
display: flex;
align-items: center;
}
.top-row ::deep a, .top-row .btn-link {
white-space: nowrap;
margin-left: 1.5rem;
}
.top-row a:first-child {
overflow: hidden;
text-overflow: ellipsis;
}
@media (max-width: 640.98px) {
.top-row:not(.auth) {
display: none;
}
.top-row.auth {
justify-content: space-between;
}
.top-row a, .top-row .btn-link {
margin-left: 0;
}
}
@media (min-width: 641px) {
.page {
flex-direction: row;
}
.sidebar {
width: 250px;
height: 100vh;
position: sticky;
top: 0;
}
.top-row {
position: sticky;
top: 0;
z-index: 1;
}
.top-row, article {
padding-left: 2rem !important;
padding-right: 1.5rem !important;
}
.right-frame {
position: absolute;
right: 1.25em;
left: 23.25em;
top: 1.25em;
bottom: 1.25em;
transition: 1s;
}

View File

@ -1,4 +1,5 @@
<div id="leftframe" class="left_frame">
@inject NavigationManager Navigation
<div id="leftframe" class="left_frame">
<div class="logo">
@ -16,22 +17,31 @@
<div class="elements_wishlisht">
<div class="add_chat">
<a href="/">
<div class="add_chat" @onclick="RedirectToNewChat" >
<div>
<span>Search</span>
<span class="plus" >+</span>
</a>
<span class="plus">+</span>
</div>
</div>
<div class="wishlist_names">
@foreach(var item in wishlist){
<section class="cont_wishlist">
<div id="wishlist_id_@item.Id" class="wishlist_name">@item.Name</div>
<img class="button_delete_chat" src="/images/icon_delete.svg" alt="Delete wishlist">
<img class="button_open_card" src="/images/icon_open_card.svg" alt="Card open">
</section>
@if(Wishlists!=null){
@foreach (var item in Wishlists)
{
<section class="cont_wishlist">
<div @onclick="() => RedirectToPage(item.Id)" class="wishlist_name" >@item.Name</div>
<img @onclick="() => DeleteWishlist(item.Id)" class="button_delete_chat" src="/images/icon_delete.svg" alt="Delete wishlist">
<img @onclick="() => RedirectToCard(item.Id)" class="button_open_card" src="/images/icon_open_card.svg" alt="Card open">
</section>
}
}else{
<div>loading ...</div>
}
</div>
</div>
@ -54,38 +64,51 @@
<script>
function changetyle() {
var element = document.getElementById('leftframe');
var computedStyles = getComputedStyle(element);
var transformValue = computedStyles.transform;
function changetyle() {
var left_frame = document.querySelector('.sidebar-menu');
var right_frame = document.querySelector('.right-frame');
var computedStyles = getComputedStyle(left_frame);
var transformValue = computedStyles.transform;
var button_open = document.querySelector('.button_open_menu');
if (transformValue === 'matrix(1, 0, 0, 1, 0, 0)') {
element.style.transform = 'translateX(-110%)';
} else {
element.style.transform = 'translateX(0%)';
}
if (transformValue === 'matrix(1, 0, 0, 1, 0, 0)') {
left_frame.style.transform = 'translateX(-110%)';
button_open.style.visibility = 'visible';
right_frame.style.left = '1.25em';
} else {
left_frame.style.transform = 'translateX(0)';
button_open.style.visibility = 'hidden';
right_frame.style.left = '23.25em';
}
}
document.getElementById('button_close').addEventListener('click', changetyle);
</script>
@code {
private List<Models.Wishlist> wishlist;
protected override async Task OnInitializedAsync()
{
wishlist = new List<Models.Wishlist>
{
new Models.Wishlist {Id = "0", Name = "Gift for Jessica", Type="product", CreateById="0"},
new Models.Wishlist {Id = "1", Name = "Secret Santa", Type="gift", CreateById="1"},
new Models.Wishlist {Id = "2", Name = "Marks Birthday", Type="product", CreateById="2"},
new Models.Wishlist {Id = "3", Name = "Garden tools", Type="product", CreateById="2"},
new Models.Wishlist {Id = "4", Name = "Phone charger ", Type="product", CreateById="2"},
new Models.Wishlist {Id = "5", Name = "Garden tools", Type="product", CreateById="2"}
};
private void RedirectToPage(string itemId) {
var url = $"/chat/{itemId}";
Navigation.NavigateTo(url);
}
private void RedirectToNewChat() {
var url = $"/";
Navigation.NavigateTo(url);
}
private void RedirectToCard(string itemId) {
var url = $"/chat/{itemId}/cart";
Navigation.NavigateTo(url);
}
private void DeleteWishlist(string itemId) {
}
}
}

View File

@ -1,25 +1,50 @@
using Microsoft.AspNetCore.Components;
using ShoppingAssistantWebClient.Web.Models;
namespace ShoppingAssistantWebClient.Web.Pages;
public partial class Wishlists : ComponentBase
{
private List<Wishlist> wishlist;
protected override async Task OnInitializedAsync()
{
wishlist = new List<Models.Wishlist>
{
new Models.Wishlist {Id = "0", Name = "Gift for Jessica", Type="product", CreateById="0"},
new Models.Wishlist {Id = "1", Name = "Secret Santa", Type="gift", CreateById="1"},
new Models.Wishlist {Id = "2", Name = "Marks Birthday", Type="product", CreateById="2"},
new Models.Wishlist {Id = "3", Name = "Garden tools", Type="product", CreateById="2"},
new Models.Wishlist {Id = "4", Name = "Phone charger ", Type="product", CreateById="2"},
new Models.Wishlist {Id = "5", Name = "Garden tools", Type="product", CreateById="2"}
};
}
}
using Microsoft.AspNetCore.Components;
using ShoppingAssistantWebClient.Web.Models;
using GraphQL;
using Newtonsoft.Json;
using ShoppingAssistantWebClient.Web.Models;
using ShoppingAssistantWebClient.Web.Network;
namespace ShoppingAssistantWebClient.Web.Shared
{
public partial class NavMenu : ComponentBase
{
public List<Wishlist> Wishlists { get; set; }
private readonly ApiClient _apiClient;
public NavMenu()
{
}
public NavMenu(ApiClient apiClient)
{
_apiClient = apiClient;
}
public async Task OnGetAsync()
{
var request = new GraphQLRequest
{
Query = @"query PersonalWishlistsPage {
personalWishlistsPage(pageNumber: $pageNumber, pageSize: $pageSize) {
items {
id
name
}
}
}
",
Variables = new
{
pageNumber = 1,
pageSize = 10,
}
};
var response = await _apiClient.QueryAsync(request);
var jsonCategoriesResponse = JsonConvert.SerializeObject(response.Data.personalWishlistsPage.items);
this.Wishlists = JsonConvert.DeserializeObject<List<Wishlist>>(jsonCategoriesResponse);
}
}
}

View File

@ -1,10 +1,3 @@
{
"DetailedErrors": true,
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"ApiUrl": "https://localhost:7268/"
}
"ApiUrl": "https://shopping-assistant-api-dev.azurewebsites.net/"
}

File diff suppressed because one or more lines are too long

Binary file not shown.

After

(image error) Size: 546 B

Binary file not shown.

After

(image error) Size: 300 B

Binary file not shown.

After

(image error) Size: 367 B

Binary file not shown.

After

(image error) Size: 406 B

Binary file not shown.

After

(image error) Size: 577 B

Binary file not shown.

After

(image error) Size: 419 B

View File

@ -1,3 +1,3 @@
<svg width="17" height="17" viewBox="0 0 17 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M14.1667 3.54169C14.3545 3.54169 14.5347 3.61631 14.6675 3.74915C14.8004 3.88199 14.875 4.06216 14.875 4.25002C14.875 4.43788 14.8004 4.61805 14.6675 4.75089C14.5347 4.88373 14.3545 4.95835 14.1667 4.95835H13.4583L13.4562 5.00865L12.7953 14.2673C12.7699 14.6247 12.61 14.9592 12.3477 15.2034C12.0855 15.4476 11.7405 15.5834 11.3822 15.5834H5.61708C5.25877 15.5834 4.91376 15.4476 4.65154 15.2034C4.38933 14.9592 4.2294 14.6247 4.20396 14.2673L3.54308 5.00935C3.54201 4.99238 3.54154 4.97536 3.54167 4.95835H2.83333C2.64547 4.95835 2.4653 4.88373 2.33247 4.75089C2.19963 4.61805 2.125 4.43788 2.125 4.25002C2.125 4.06216 2.19963 3.88199 2.33247 3.74915C2.4653 3.61631 2.64547 3.54169 2.83333 3.54169H14.1667ZM12.0395 4.95835H4.96046L5.61779 14.1667H11.3822L12.0395 4.95835ZM9.91667 1.41669C10.1045 1.41669 10.2847 1.49131 10.4175 1.62415C10.5504 1.75699 10.625 1.93716 10.625 2.12502C10.625 2.31288 10.5504 2.49305 10.4175 2.62589C10.2847 2.75873 10.1045 2.83335 9.91667 2.83335H7.08333C6.89547 2.83335 6.7153 2.75873 6.58247 2.62589C6.44963 2.49305 6.375 2.31288 6.375 2.12502C6.375 1.93716 6.44963 1.75699 6.58247 1.62415C6.7153 1.49131 6.89547 1.41669 7.08333 1.41669H9.91667Z" fill="#202124"/>
</svg>
<svg width="17" height="17" viewBox="0 0 17 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M14.1667 3.54169C14.3545 3.54169 14.5347 3.61631 14.6675 3.74915C14.8004 3.88199 14.875 4.06216 14.875 4.25002C14.875 4.43788 14.8004 4.61805 14.6675 4.75089C14.5347 4.88373 14.3545 4.95835 14.1667 4.95835H13.4583L13.4562 5.00865L12.7953 14.2673C12.7699 14.6247 12.61 14.9592 12.3477 15.2034C12.0855 15.4476 11.7405 15.5834 11.3822 15.5834H5.61708C5.25877 15.5834 4.91376 15.4476 4.65154 15.2034C4.38933 14.9592 4.2294 14.6247 4.20396 14.2673L3.54308 5.00935C3.54201 4.99238 3.54154 4.97536 3.54167 4.95835H2.83333C2.64547 4.95835 2.4653 4.88373 2.33247 4.75089C2.19963 4.61805 2.125 4.43788 2.125 4.25002C2.125 4.06216 2.19963 3.88199 2.33247 3.74915C2.4653 3.61631 2.64547 3.54169 2.83333 3.54169H14.1667ZM12.0395 4.95835H4.96046L5.61779 14.1667H11.3822L12.0395 4.95835ZM9.91667 1.41669C10.1045 1.41669 10.2847 1.49131 10.4175 1.62415C10.5504 1.75699 10.625 1.93716 10.625 2.12502C10.625 2.31288 10.5504 2.49305 10.4175 2.62589C10.2847 2.75873 10.1045 2.83335 9.91667 2.83335H7.08333C6.89547 2.83335 6.7153 2.75873 6.58247 2.62589C6.44963 2.49305 6.375 2.31288 6.375 2.12502C6.375 1.93716 6.44963 1.75699 6.58247 1.62415C6.7153 1.49131 6.89547 1.41669 7.08333 1.41669H9.91667Z" fill="#202124"/>
</svg>

Before

(image error) Size: 1.3 KiB

After

(image error) Size: 1.3 KiB

View File

@ -1,4 +1,4 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.96249 11.8808C2.36416 9.08668 2.06416 7.68918 2.81499 6.76168C3.56499 5.83334 4.99416 5.83334 7.85166 5.83334H12.1483C15.0067 5.83334 16.4342 5.83334 17.185 6.76168C17.935 7.69001 17.6358 9.08668 17.0375 11.8808L16.68 13.5475C16.2742 15.4417 16.0717 16.3883 15.3842 16.9442C14.6967 17.5 13.7283 17.5 11.7917 17.5H8.20833C6.27166 17.5 5.30333 17.5 4.61666 16.9442C3.92833 16.3883 3.72499 15.4417 3.31999 13.5475L2.96249 11.8808Z" stroke="black" stroke-width="1.5"/>
<path d="M2.5 9.16667H17.5M8.33333 11.6667H11.6667M15 7.5L12.5 2.5M5 7.5L7.5 2.5" stroke="black" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.96249 11.8808C2.36416 9.08668 2.06416 7.68918 2.81499 6.76168C3.56499 5.83334 4.99416 5.83334 7.85166 5.83334H12.1483C15.0067 5.83334 16.4342 5.83334 17.185 6.76168C17.935 7.69001 17.6358 9.08668 17.0375 11.8808L16.68 13.5475C16.2742 15.4417 16.0717 16.3883 15.3842 16.9442C14.6967 17.5 13.7283 17.5 11.7917 17.5H8.20833C6.27166 17.5 5.30333 17.5 4.61666 16.9442C3.92833 16.3883 3.72499 15.4417 3.31999 13.5475L2.96249 11.8808Z" stroke="black" stroke-width="1.5"/>
<path d="M2.5 9.16667H17.5M8.33333 11.6667H11.6667M15 7.5L12.5 2.5M5 7.5L7.5 2.5" stroke="black" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

Before

(image error) Size: 745 B

After

(image error) Size: 749 B

Binary file not shown.

After

(image error) Size: 3.0 KiB

Binary file not shown.

After

(image error) Size: 4.3 KiB

Binary file not shown.

After

(image error) Size: 559 B

Binary file not shown.

After

(image error) Size: 242 B

Binary file not shown.

After

(image error) Size: 387 B

File diff suppressed because one or more lines are too long

Before

(image error) Size: 9.6 KiB

After

(image error) Size: 9.6 KiB

Binary file not shown.

After

(image error) Size: 424 B

Binary file not shown.

After

(image error) Size: 440 B

Binary file not shown.

After

(image error) Size: 348 B

Binary file not shown.

After

(image error) Size: 249 B