diff --git a/ShoppingAssistantWebClient.Web/Models/Messages.cs b/ShoppingAssistantWebClient.Web/Models/Messages.cs new file mode 100644 index 0000000..9cbed36 --- /dev/null +++ b/ShoppingAssistantWebClient.Web/Models/Messages.cs @@ -0,0 +1,14 @@ +namespace ShoppingAssistantWebClient.Web.Models +{ + public class Messages + { + + public required string Id { get; set; } + + public required string Text { get; set; } + + public required string Role { get; set; } + + public required string CreatedById { get; set; } + } +} diff --git a/ShoppingAssistantWebClient.Web/Network/ApiClient.cs b/ShoppingAssistantWebClient.Web/Network/ApiClient.cs index 9688c66..f7b6532 100644 --- a/ShoppingAssistantWebClient.Web/Network/ApiClient.cs +++ b/ShoppingAssistantWebClient.Web/Network/ApiClient.cs @@ -2,6 +2,7 @@ using GraphQL; using Newtonsoft.Json; using System.Net.Http.Headers; +using ShoppingAssistantWebClient.Web.Models.GlobalInstances; namespace ShoppingAssistantWebClient.Web.Network; @@ -29,7 +30,9 @@ public class ApiClient { await SetAuthenticationAsync(); - return await _graphQLClient.SendQueryAsync(request); + var response = await _graphQLClient.SendQueryAsync(request); + + return response; } public async Task QueryAsync(GraphQLRequest request, string propertyName) @@ -116,7 +119,18 @@ public class ApiClient private async Task SetAuthenticationAsync() { - _graphQLClient.HttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", this.JwtToken); - _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", this.JwtToken); + var accessToken = await _authenticationService.GetAuthTokenAsync(); + if (!string.IsNullOrEmpty(accessToken)) + { + this.JwtToken = accessToken; + + GlobalUser.Id = _authenticationService.GetIdFromJwtToken(accessToken); + GlobalUser.Email = _authenticationService.GetEmailFromJwtToken(accessToken); + GlobalUser.Phone = _authenticationService.GetPhoneFromJwtToken(accessToken); + GlobalUser.Roles = _authenticationService.GetRolesFromJwtToken(accessToken); + + _graphQLClient.HttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", this.JwtToken); + _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", this.JwtToken); + } } } \ No newline at end of file diff --git a/ShoppingAssistantWebClient.Web/Pages/Chat.razor b/ShoppingAssistantWebClient.Web/Pages/Chat.razor index b79f8ce..939c8e8 100644 --- a/ShoppingAssistantWebClient.Web/Pages/Chat.razor +++ b/ShoppingAssistantWebClient.Web/Pages/Chat.razor @@ -1,133 +1,107 @@ -@page "/chat/1" - -
- -
- - - - - - - -
- -
- - - - -
- -
- -
Gift for Jessica
- -
    - -
  • -

    Give me product recommendation. Ask me questions if you need more directions. I am looking for: hub for my macbook to connect external monitors

    -
  • -
  • -

    Sure! I can help you with that. I will ask you some leading questions. This is the first: -
    - How many external monitors do you want to connect to your MacBook?

    -
  • -
  • -

    7

    -
  • -
  • -

    Thank you. Here is the next question: -
    - What type of external monitors do you have? (e.g., HDMI, DisplayPort, VGA)

    -
  • - -
- - - - -
- - - - - Send message - - - -
- - -
-
- -
-
- +@page "/chat/{chatId}" + +@inject IHttpClientFactory ClientFactory + +Gift for Jessica + +
+ + + + +
+
+ + +
Gift for Jessica
+ +
    + + @if(!isLoading && Messages!=null){ + + @foreach (var item in Messages){ + + if(item.Role!="User"){ + +
  • +

    @item.Text

    +
  • + + }else{ + +
  • +

    @item.Text

    +
  • + + } + } + + } + +
+ + +
+ + +
+ +
Several possible options
+ +
+ +
+ HDMI +
+
+ VGA +
+
+ DisplayPort +
+ +
+ +
+ + +
+ + Send message +
+ +
+ +
+ + + +@code { + + [Parameter] public string chatId { get; set; } + + protected override async Task OnParametersSetAsync() + { + await LoadMessages(); + } + + public void Enter(KeyboardEventArgs e) + { + if (e.Code == "Enter" || e.Code == "NumpadEnter") + { + AddNewMessage(); + } + } + +} \ No newline at end of file diff --git a/ShoppingAssistantWebClient.Web/Pages/Chat.razor.cs b/ShoppingAssistantWebClient.Web/Pages/Chat.razor.cs index 3c8cbd7..6fbee2d 100644 --- a/ShoppingAssistantWebClient.Web/Pages/Chat.razor.cs +++ b/ShoppingAssistantWebClient.Web/Pages/Chat.razor.cs @@ -1,14 +1,101 @@ using Microsoft.AspNetCore.Components; +using ShoppingAssistantWebClient.Web.Models; +using GraphQL; +using Newtonsoft.Json; +using ShoppingAssistantWebClient.Web.Network; namespace ShoppingAssistantWebClient.Web.Pages; public partial class Chat : ComponentBase { - [Inject] - public ILogger Logger { get; set; } - protected override async Task OnInitializedAsync() - { - // Get data from Back-end - } + [Inject] + private ApiClient _apiClient { get; set; } + + public List Messages { get; set; } + public bool isLoading = true; + private string inputValue = ""; + protected override async Task OnInitializedAsync() + { + await LoadMessages(); + } + + + private async Task LoadMessages() + { + + + isLoading = true; + int pageNumber = 1; + string wishlistId = chatId; + var request = new GraphQLRequest + { + Query = @"query MessagesPageFromPersonalWishlist($wishlistId: String!, $pageNumber: Int!, $pageSize: Int!) { + messagesPageFromPersonalWishlist( wishlistId: $wishlistId, pageNumber: $pageNumber, pageSize: $pageSize) + { + items { + id + text + role + createdById + } + } + }", + + Variables = new + { + wishlistId, + pageNumber, + pageSize = 20 + } + }; + try{ + var response = await _apiClient.QueryAsync(request); + var responseData = response.Data; + var jsonCategoriesResponse = JsonConvert.SerializeObject(responseData.messagesPageFromPersonalWishlist.items); + this.Messages = JsonConvert.DeserializeObject>(jsonCategoriesResponse); + Messages.Reverse(); + isLoading = false; + + }catch{ + + } + + + } + private async Task AddNewMessage() + { + + isLoading = true; + var pageNumber = 1; + var wishlistId = chatId; + var text = inputValue; + inputValue=""; + var request = new GraphQLRequest + { + Query = @"mutation AddMessageToPersonalWishlist($wishlistId: String!, $text: String!) { + addMessageToPersonalWishlist(wishlistId: $wishlistId, dto: { text: $text }) { + id + text + role + createdById + } + } + ", + + Variables = new + { + wishlistId, + text + } + }; + + var response = await _apiClient.QueryAsync(request); + await LoadMessages(); + } + + + + + } diff --git a/ShoppingAssistantWebClient.Web/Pages/Chat.razor.css b/ShoppingAssistantWebClient.Web/Pages/Chat.razor.css index 28694d7..495038c 100644 --- a/ShoppingAssistantWebClient.Web/Pages/Chat.razor.css +++ b/ShoppingAssistantWebClient.Web/Pages/Chat.razor.css @@ -1,330 +1,139 @@ -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; - } +.right_frame { + position: relative; + border: 0.09em solid; + border-color: #0052CC; + border-radius: 0.6em; + height: 100%; + width: 100%; +} + - .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; +.button_open_menu { + z-index: 2; + width: 1.43em; + height: 1.23em; + position: absolute; + top: 1.56em; + left: 1.56em; + cursor: pointer; + visibility: hidden; +} + +.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: 1.25em; + color: #0052CC; + font-size: 1.0625em; + text-align: center; +} + +.chat_input { + background-color: #EAEAEA; + position: absolute; + display: flex; + align-items: center; + bottom: 2em; + margin-left: 25%; + width: 50%; + border-radius: 0.6em; +} + +.possible_options { + visibility: hidden; + position: absolute; + bottom: 5.5em; + margin-left: 25%; + width: 50%; + border-radius: 0.6em; +} +.tite_options{ + font-size: 0.9em; + color: #ADADAD; + margin-bottom: 0.5em; + +} +.options{ + justify-content: space-between; + align-items: center; + font-size: 1em; +} +.topic_options +{ + display: inline-block; + padding: 0.5em; + border: 0.09em 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; + border-radius: 0.6em; + margin: 0em 0.6em; + flex: 1; 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; - } - +} + +.input_messages { + width: 100%; + height: 2.5em; + font-size: 1.0625em; + background-color: #EAEAEA; + color: #4E4E4E; + border-radius: 0.6em; + border: none; + padding: 0.625em 1.25em; + outline: none; +} + +.button_sende { + float: right; + cursor: pointer; + line-height: 2.5em; + margin-right: 0.8em; + width: 1.5em; + height: 1.4em; +} + +.new_chat { + padding-top: 0.5em; + position: relative; + height: 100%; + width: 100%; +} + +.chat_message { + position: relative; + overflow-y: auto; + height: calc(100% - 5.5em); + width: 100%; +} +.chat_message::-webkit-scrollbar { + border-radius: 20px; + width: 0.2em; +} + +.chat_message::-webkit-scrollbar-thumb { + background-color: #0052CC; + /* Колір позиції покажчика */ + border-radius: 10px; + /* Закруглення країв позиції покажчика */ + width: 0.2em; +} + + .chat_box{ border-radius: 10px; position: absolute; diff --git a/ShoppingAssistantWebClient.Web/Pages/Index.razor b/ShoppingAssistantWebClient.Web/Pages/Index.razor index e95f25b..59320ca 100644 --- a/ShoppingAssistantWebClient.Web/Pages/Index.razor +++ b/ShoppingAssistantWebClient.Web/Pages/Index.razor @@ -1,9 +1,105 @@ @page "/" -CartaId +New Chat -

Hello, world!

+
-Welcome to your new app. + - + +
+
+
New chat
+
What you're looking for
+ +
+
+ Product +
+
+ Gift +
+
+ + +
What you're looking for, we will help you solve your problem and find it +
+ + + +
+
+ + Send message +
+ +
+ +
+ + +@code{ + private string selectedChoice = "Product"; + + private void Сhoose_product() { + selectedChoice = "Product"; + } + private void Сhoose_gift() { + selectedChoice = "Gift"; + } +} diff --git a/ShoppingAssistantWebClient.Web/Pages/Index.razor.cs b/ShoppingAssistantWebClient.Web/Pages/Index.razor.cs new file mode 100644 index 0000000..601e4a9 --- /dev/null +++ b/ShoppingAssistantWebClient.Web/Pages/Index.razor.cs @@ -0,0 +1,57 @@ +using Microsoft.AspNetCore.Components; +using ShoppingAssistantWebClient.Web.Models; +using GraphQL; +using Newtonsoft.Json; +using ShoppingAssistantWebClient.Web.Network; + + +namespace ShoppingAssistantWebClient.Web.Pages +{ + public partial class Index : ComponentBase + { + + [Inject] + private ApiClient _apiClient { get; set; } + [Inject] + private NavigationManager Navigation { get; set; } + + private string inputValue = ""; + public bool isLoading = true; + + + private async Task CreateNewChat() { + + if(inputValue!=""){ + + var type = selectedChoice; + + var firstMessageText= inputValue; + var request = new GraphQLRequest + { + Query = @"mutation StartPersonalWishlist($type: String!, $firstMessageText: String!) { + startPersonalWishlist(dto: { type: $type, firstMessageText: $firstMessageText }) { + id + } + } + ", + + Variables = new + { + type, + firstMessageText + } + }; + + var response = await _apiClient.QueryAsync(request); + var responseData = response.Data; + var chat_id = responseData.startPersonalWishlist.id; + var url = $"/chat/{chat_id}"; + Navigation.NavigateTo(url); + + } + + + } + + } +} diff --git a/ShoppingAssistantWebClient.Web/Pages/Index.razor.css b/ShoppingAssistantWebClient.Web/Pages/Index.razor.css new file mode 100644 index 0000000..854d315 --- /dev/null +++ b/ShoppingAssistantWebClient.Web/Pages/Index.razor.css @@ -0,0 +1,187 @@ +.right_frame { + position: relative; + border: 0.09em solid; + border-color: #0052CC; + border-radius: 0.6em; + height: 100%; + width: 100%; +} + +.button_open_menu { + z-index: 2; + width: 1.43em; + height: 1.23em; + position: absolute; + top: 1.56em; + left: 1.56em; + cursor: pointer; + visibility: hidden; +} + +.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: 1.25em; + color: #0052CC; + font-size: 1.0625em; + text-align: center; +} + +.title_two_frame { + padding-top: 2.25em; + padding-bottom: 1.5em; + font-size: 2.5em; + text-align: center; + font-weight: 600; +} + +.title_three_frame { + padding-top: 3.75em; + padding-bottom: 2.5em; + color: #202124; + font-size: 1.25em; + text-align: center; + font-weight: 400; +} + +.topic { + font-size: 1.125em; + text-align: center; + line-height: 2.1875em; + color: #009FFF; + width: 15.625em; + margin: 0 auto; +} + +.topic div { + margin-top: 1.25em; + border: 0.09em solid; + border-color: #009FFF; + border-radius: 0.6em; + justify-content: center; + align-items: center; + cursor: pointer; +} + +.topic div a { + color: #009FFF; + text-decoration: none; +} + +.switch { + height: 2.8125em; + width: 21.875em; + margin: 0 auto; + border: 0.09em solid; + border-color: #EAEAEA; + border-radius: 0.6em; + text-align: center; + position: relative; +} + +.switch_product { + position: absolute; + background-color: #0052CC; + border-radius: 0.6em; + margin: 0.3125em; + width: calc(50% - 0.625em); + height: calc(100% - 0.625em); + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + transition: 0.8s; + color: white; +} + +.switch_gift { + right: 0; + position: absolute; + border-radius: 0.6em; + margin: 0.3125em; + width: calc(50% - 0.625em); + height: calc(100% - 0.625em); + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + transition: 0.8s; + color: #202124; +} + +.chat_message { + position: relative; + overflow-y: auto; + height: calc(100% - 5.5em); + width: 100%; +} + +.chat_input { + background-color: #EAEAEA; + position: absolute; + display: flex; + align-items: center; + bottom: 2em; + margin-left: 25%; + width: 50%; + border-radius: 0.6em; +} + +.input_messages { + width: 100%; + height: 2.5em; + font-size: 1.0625em; + background-color: #EAEAEA; + color: #4E4E4E; + border-radius: 0.6em; + border: none; + padding: 0.625em 1.25em; + outline: none; +} + +.button_sende { + float: right; + cursor: pointer; + line-height: 2.5em; + margin-right: 0.8em; + width: 1.8em; + height: 1.7em; +} + + +.new_chat { + padding-top: 0.5em; + position: relative; + height: 100%; + width: 100%; +} + + +.chat_message::-webkit-scrollbar { + border-radius: 20px; + width: 0.2em; +} + +.chat_message::-webkit-scrollbar-thumb { + background-color: #0052CC; + /* Колір позиції покажчика */ + border-radius: 10px; + /* Закруглення країв позиції покажчика */ + width: 0.2em; +} \ No newline at end of file diff --git a/ShoppingAssistantWebClient.Web/Program.cs b/ShoppingAssistantWebClient.Web/Program.cs index 50d5733..4a9cc04 100644 --- a/ShoppingAssistantWebClient.Web/Program.cs +++ b/ShoppingAssistantWebClient.Web/Program.cs @@ -1,5 +1,7 @@ +using GraphQL.Client.Http; using ShoppingAssistantWebClient.Web.Configurations; using ShoppingAssistantWebClient.Web.Data; +using ShoppingAssistantWebClient.Web.Network; var builder = WebApplication.CreateBuilder(args); @@ -28,6 +30,7 @@ app.UseRouting(); app.MapBlazorHub(); app.MapFallbackToPage("/_Host"); -app.ConfigureGlobalUserMiddleware(); +// Login moved to ApiClient +// app.ConfigureGlobalUserMiddleware(); app.Run(); diff --git a/ShoppingAssistantWebClient.Web/Shared/MainLayout.razor b/ShoppingAssistantWebClient.Web/Shared/MainLayout.razor index 0a22716..196375a 100644 --- a/ShoppingAssistantWebClient.Web/Shared/MainLayout.razor +++ b/ShoppingAssistantWebClient.Web/Shared/MainLayout.razor @@ -1,15 +1,12 @@ @inherits LayoutComponentBase -ShoppingAssistantWebClient.Web +CARTAID
+
+ @Body
-
diff --git a/ShoppingAssistantWebClient.Web/Shared/MainLayout.razor.css b/ShoppingAssistantWebClient.Web/Shared/MainLayout.razor.css index 950f666..0f1cc15 100644 --- a/ShoppingAssistantWebClient.Web/Shared/MainLayout.razor.css +++ b/ShoppingAssistantWebClient.Web/Shared/MainLayout.razor.css @@ -1,73 +1,24 @@ - .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; +} \ No newline at end of file diff --git a/ShoppingAssistantWebClient.Web/Shared/NavMenu.razor b/ShoppingAssistantWebClient.Web/Shared/NavMenu.razor index 3b82f08..08dd11c 100644 --- a/ShoppingAssistantWebClient.Web/Shared/NavMenu.razor +++ b/ShoppingAssistantWebClient.Web/Shared/NavMenu.razor @@ -1,5 +1,7 @@ -
+@using Models.GlobalInstances +@inject NavigationManager Navigation +
@code { - -private List wishlist; - - protected override async Task OnInitializedAsync() - { - - wishlist = new List - { - 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 = "Mark’s 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 async void DeleteWishlist(string itemId) { + + await DeleteWish(itemId); + + } + + public void UpdateSideMenu() + { + StateHasChanged(); + } } diff --git a/ShoppingAssistantWebClient.Web/Shared/NavMenu.razor.cs b/ShoppingAssistantWebClient.Web/Shared/NavMenu.razor.cs index b31509d..b4ca1e9 100644 --- a/ShoppingAssistantWebClient.Web/Shared/NavMenu.razor.cs +++ b/ShoppingAssistantWebClient.Web/Shared/NavMenu.razor.cs @@ -1,25 +1,72 @@ - -using Microsoft.AspNetCore.Components; -using ShoppingAssistantWebClient.Web.Models; - -namespace ShoppingAssistantWebClient.Web.Pages; - -public partial class Wishlists : ComponentBase -{ -private List wishlist; - - protected override async Task OnInitializedAsync() - { - - wishlist = new List - { - 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 = "Mark’s 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.Network; + +namespace ShoppingAssistantWebClient.Web.Shared +{ + public partial class NavMenu : ComponentBase + { + + [Inject] + private ApiClient _apiClient { get; set; } + public List Wishlists { get; set; } + public bool isLoading = true; + protected override async Task OnInitializedAsync() + { + await LoadMenus(); + } + private async Task LoadMenus() + { + isLoading = true; + var pageNumber = 1; + var request = new GraphQLRequest + { + Query = @"query PersonalWishlistsPage( $pageNumber: Int!, $pageSize: Int!) { + personalWishlistsPage(pageNumber: $pageNumber, pageSize: $pageSize) { + items { + id + name + } + } + }", + + Variables = new + { + pageNumber, + pageSize = 10, + } + }; + + var response = await _apiClient.QueryAsync(request); + var responseData = response.Data; + var jsonCategoriesResponse = JsonConvert.SerializeObject(responseData.personalWishlistsPage.items); + this.Wishlists = JsonConvert.DeserializeObject>(jsonCategoriesResponse); + isLoading = false; + } + + protected async Task DeleteWish(string wishlistId) + { + var request = new GraphQLRequest + { + Query = @"mutation DeletePersonalWishlist($wishlistId: String!) { + deletePersonalWishlist(wishlistId: $wishlistId) { + id + } + } + ", + + Variables = new + { + wishlistId + } + }; + + var response = await _apiClient.QueryAsync(request); + await LoadMenus(); + } + + } + +} \ No newline at end of file diff --git a/ShoppingAssistantWebClient.Web/Shared/NavMenu.razor.css b/ShoppingAssistantWebClient.Web/Shared/NavMenu.razor.css index 7d7ef76..091f52e 100644 --- a/ShoppingAssistantWebClient.Web/Shared/NavMenu.razor.css +++ b/ShoppingAssistantWebClient.Web/Shared/NavMenu.razor.css @@ -4,7 +4,6 @@ height: 100%; width: 100%; transition: 1s; - transform: translateX(0%); } .logo { height: 5em; @@ -39,7 +38,7 @@ align-items: center; border-radius: 0 0 0.6em 0.6em; background-color: rgb(255, 255, 255); - height: 4em; + height: 3.6em; left: 0; bottom: 0; width: 100%; @@ -64,12 +63,14 @@ } .wishlist_name { padding-left: 0.7em; + padding-right: 5em; width: 10.5em; white-space: nowrap; overflow: hidden; position: absolute; height: 2.5em; line-height: 2.5em; + cursor: pointer; } .cont_wishlist { margin-top: 0.4375em; @@ -79,7 +80,7 @@ font-size: 1.1em; width: 100%; height:2.5em; - cursor: pointer; + } .cont_wishlist:hover { background-color: #e6e6e6; @@ -90,29 +91,40 @@ } .cont_wishlist:hover .button_open_card{ visibility: visible; + } .button_delete_chat { - margin-top: 0.65em; + cursor: pointer; + margin-top: 0.55em; margin-right: 1em; float: right; position: relative; visibility: hidden; - height: 1.2em; - width: 1.2em; + height: 1.4em; + width: 1.4em; } .button_open_card { - margin-top: 0.65em; + cursor: pointer; + position: relative; + z-index: 999; + margin-top: 0.55em; margin-right: 1em; float: right; visibility: hidden; - height: 1.2em; - width: 1.3em; + height: 1.4em; + width: 1.5em; } .elements_wishlisht::-webkit-scrollbar { - background-color: #009FFF; border-radius: 20px; width: 0.2em; } + +.elements_wishlisht::-webkit-scrollbar-thumb { + background-color: #0052CC; /* Колір позиції покажчика */ + border-radius: 10px; /* Закруглення країв позиції покажчика */ + width: 0.2em; +} + .add_chat { margin-bottom: 0.3125em; background-color: #0165FF; @@ -123,7 +135,7 @@ cursor: pointer; line-height: 2.5em; } -.add_chat a { +.add_chat div { justify-content: center; align-items: center; border-radius: 0.6em; diff --git a/ShoppingAssistantWebClient.Web/Shared/SurveyPrompt.razor b/ShoppingAssistantWebClient.Web/Shared/SurveyPrompt.razor deleted file mode 100644 index b31a4a6..0000000 --- a/ShoppingAssistantWebClient.Web/Shared/SurveyPrompt.razor +++ /dev/null @@ -1,16 +0,0 @@ -
- - @Title - - - Please take our - brief survey - - and tell us what you think. -
- -@code { - // Demonstrates how a parent component can supply parameters - [Parameter] - public string? Title { get; set; } -} diff --git a/ShoppingAssistantWebClient.Web/appsettings.Development.json b/ShoppingAssistantWebClient.Web/appsettings.Development.json index 9a8322f..dadb342 100644 --- a/ShoppingAssistantWebClient.Web/appsettings.Development.json +++ b/ShoppingAssistantWebClient.Web/appsettings.Development.json @@ -1,3 +1,5 @@ { "ApiUrl": "https://shopping-assistant-api-dev.azurewebsites.net/" } + + diff --git a/ShoppingAssistantWebClient.Web/wwwroot/images/send.png b/ShoppingAssistantWebClient.Web/wwwroot/images/send.png deleted file mode 100644 index 2793f03..0000000 Binary files a/ShoppingAssistantWebClient.Web/wwwroot/images/send.png and /dev/null differ diff --git a/ShoppingAssistantWebClient.Web/wwwroot/images/send.svg b/ShoppingAssistantWebClient.Web/wwwroot/images/send.svg new file mode 100644 index 0000000..34fabba --- /dev/null +++ b/ShoppingAssistantWebClient.Web/wwwroot/images/send.svg @@ -0,0 +1,3 @@ + + +