Crud implemented by Contact

This commit is contained in:
2023-04-19 17:25:42 +02:00
parent 0234db870b
commit ede368b963
10 changed files with 334 additions and 31 deletions

View File

@ -1,5 +1,6 @@
@page "/contacts" @page "/contacts"
@inject NavigationManager NavigationManager @inject NavigationManager NavigationManager
@inject HttpClient Http
<h3>Contacts</h3> <h3>Contacts</h3>
<SfGrid DataSource="GridData" AllowFiltering="true" Toolbar="@(new List<string>() {"Search"})"> <SfGrid DataSource="GridData" AllowFiltering="true" Toolbar="@(new List<string>() {"Search"})">
@ -14,6 +15,15 @@
} }
</Template> </Template>
</GridColumn> </GridColumn>
<GridColumn Width="60">
<Template>
@{
var contact = context as Contact;
<SfButton CssClass="e-inherit" IconCss="e-icons e-delete"
OnClick="@(() => DeleteContact(contact!))"></SfButton>
}
</Template>
</GridColumn>
<GridColumn Field="FirstName" HeaderText="First Name"></GridColumn> <GridColumn Field="FirstName" HeaderText="First Name"></GridColumn>
<GridColumn Field="LastName" HeaderText="Last Name"></GridColumn> <GridColumn Field="LastName" HeaderText="Last Name"></GridColumn>
<GridColumn Field="NickName" HeaderText="Nick Name"></GridColumn> <GridColumn Field="NickName" HeaderText="Nick Name"></GridColumn>
@ -23,43 +33,108 @@
</SfGrid> </SfGrid>
<p>
<SfButton IsPrimary="true" Content="Create New Contact" OnClick="CreateContact" />
</p>
<SfDialog Width="335px" IsModal="true" @bind-Visible="showDeleteDialog">
<DialogTemplates>
<Header>Are you sure?</Header>
<Content>
<p>Do you really want to delete @contactToDelete!.NickName</p>
</Content>
</DialogTemplates>
<DialogButtons>
<DialogButton Content="Yep." IsPrimary="false" OnClick="ConfirmDeleteContact"></DialogButton>
<DialogButton Content="Nope." IsPrimary="true" OnClick="CancelDeleteContact"></DialogButton>
</DialogButtons>
<DialogAnimationSettings Effect="@DialogEffect.Zoom" ></DialogAnimationSettings>
</SfDialog>
@code { @code {
Contact? contactToDelete;
public List<Contact> GridData { get; set; } = new List<Contact> public List<Contact> GridData { get; set; } = new List<Contact>
{ {
new Contact //new Contact
{ //{
Id = 1, // Id = 1,
FirstName = "Peter", // FirstName = "Peter",
LastName = "Parker", // LastName = "Parker",
NickName = "Spider-Man", // NickName = "Spider-Man",
Place = "New York City", // Place = "New York City",
DateOfBirth = new DateTime(2001, 8, 1), // DateOfBirth = new DateTime(2001, 8, 1),
DateCreated = DateTime.Now // DateCreated = DateTime.Now
}, //},
new Contact //new Contact
{ //{
Id = 1, // Id = 1,
FirstName = "Tony", // FirstName = "Tony",
LastName = "Stark", // LastName = "Stark",
NickName = "Iron Man", // NickName = "Iron Man",
Place = "Malibu", // Place = "Malibu",
DateOfBirth = new DateTime(1970, 5, 29), // DateOfBirth = new DateTime(1970, 5, 29),
DateCreated = DateTime.Now // DateCreated = DateTime.Now
}, //},
new Contact //new Contact
{ //{
Id = 1, // Id = 1,
FirstName = "Bruce", // FirstName = "Bruce",
LastName = "Wayne", // LastName = "Wayne",
NickName = "Batman", // NickName = "Batman",
Place = "Gotham City", // Place = "Gotham City",
DateOfBirth = new DateTime(1915, 4, 7), // DateOfBirth = new DateTime(1915, 4, 7),
DateCreated = DateTime.Now // DateCreated = DateTime.Now
} //}
}; };
bool showDeleteDialog = false;
protected override async Task OnInitializedAsync()
{
var result = await Http.GetFromJsonAsync<List<Contact>>("api/contacts");
if(result is not null)
{
GridData = result;
}
}
void EditContact(int Id) void EditContact(int Id)
{ {
NavigationManager.NavigateTo($"contacts/edit/{Id}"); NavigationManager.NavigateTo($"contacts/edit/{Id}");
} }
void CreateContact()
{
NavigationManager.NavigateTo($"contacts/new");
}
void DeleteContact(Contact contact)
{
contactToDelete = contact;
showDeleteDialog = true;
}
void CancelDeleteContact()
{
showDeleteDialog = false;
}
async Task ConfirmDeleteContact()
{
if(contactToDelete is null)
{
return;
}
showDeleteDialog = false;
var result = await Http.DeleteAsync($"api/contacts/{contactToDelete.Id}");
if (result.IsSuccessStatusCode)
{
var jsonResult = await result.Content.ReadFromJsonAsync<List<Contact>>();
if(jsonResult is not null)
{
GridData = jsonResult;
}
}
}
} }

View File

@ -0,0 +1,91 @@
@page "/contacts/edit/{id:int}"
@page "/contacts/new"
@inject HttpClient Http
@inject NavigationManager NavigationManager
@if (Id is not null)
{
<h3>Edit @contact.NickName</h3>
}
else
{
<h3>Create a new contact</h3>
}
<div>
<EditForm Model="contact" OnValidSubmit="HandleSubmit">
<DataAnnotationsValidator />
<SfTextBox CssClass="e-outLine" Placeholder="First Name"
FloatLabelType="@FloatLabelType.Auto" @bind-Value="contact.FirstName" />
<SfTextBox CssClass="e-outLine" Placeholder="Last Name"
FloatLabelType="@FloatLabelType.Auto" @bind-Value="contact.LastName" />
<SfTextBox CssClass="e-outLine" Placeholder="Nick Name"
FloatLabelType="@FloatLabelType.Auto" @bind-Value="contact.NickName" />
<ValidationMessage For="(() => contact.NickName)" />
<SfTextBox CssClass="e-outLine" Placeholder="Place"
FloatLabelType="@FloatLabelType.Auto" @bind-Value="contact.Place" />
<SfDatePicker TValue="DateTime?" Placeholder="Date of Birth"
FloatLabelType="@FloatLabelType.Auto" @bind-Value="contact.DateOfBirth"
Format="yyyy-MM-dd"/>
<hr />
<SfButton CssClass="e-primary" IconCss="e-icons e-save" Content="Save" type="submit" />
</EditForm>
</div>
<p>
<SfMessage Severity="MessageSeverity.Success" Visible="showSuccessMessage">
Contact saved successfully.
</SfMessage>
<SfMessage Severity="MessageSeverity.Error" Visible="showErrorMessage">
Oops, something went wrong.
</SfMessage>
</p>
@code {
[Parameter]
public int? Id { get; set; }
public Contact contact { get; set; } = new Contact();
bool showSuccessMessage = false;
bool showErrorMessage = false;
protected override async Task OnInitializedAsync()
{
if(Id is not null)
{
var result = await Http.GetAsync($"api/contacts/{Id}");
if (result.IsSuccessStatusCode)
{
var jsonResult = await result.Content.ReadFromJsonAsync<Contact>();
if (jsonResult is not null)
contact = jsonResult;
}
else
{
NavigationManager.NavigateTo("/contacts/new");
}
}
}
async Task HandleSubmit()
{
HttpResponseMessage result;
if (Id is not null)
result = await Http.PutAsJsonAsync($"api/contacts/{contact.Id}", contact);
else
result = await Http.PostAsJsonAsync($"api/contacts/", contact);
if (result.IsSuccessStatusCode)
{
var jsonResult = await result.Content.ReadFromJsonAsync<Contact>();
if(jsonResult is not null)
{
contact = jsonResult;
showSuccessMessage = true;
}
}
else
{
showErrorMessage = true;
}
}
}

View File

@ -0,0 +1,3 @@
div {
width: 500px;
}

View File

@ -10,7 +10,8 @@
<SfButton CssClass="e-inherit" IconCss="e-icons e-notes" Content="Notes" <SfButton CssClass="e-inherit" IconCss="e-icons e-notes" Content="Notes"
OnClick="@(()=> NavigateToPage("/notes"))" /> OnClick="@(()=> NavigateToPage("/notes"))" />
<AppBarSpacer></AppBarSpacer> <AppBarSpacer></AppBarSpacer>
<SfButton CssClass="e-inherit" IconCss="e-icons e-plus" Content="New Contact" /> <SfButton CssClass="e-inherit" IconCss="e-icons e-plus"
Content="New Contact" OnClick="@(() => NavigateToPage("/contacts/new"))" />
</SfAppBar> </SfAppBar>

View File

@ -3,6 +3,7 @@
@using Microsoft.AspNetCore.Components.Routing @using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web @using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.Components.WebAssembly.Http @using Microsoft.AspNetCore.Components.WebAssembly.Http
@using Microsoft.AspNetCore.Components.Forms;
@using Microsoft.JSInterop @using Microsoft.JSInterop
@using BlazorSyncfusionCrm.Client.Shared @using BlazorSyncfusionCrm.Client.Shared
@using BlazorSyncfusionCrm.Client @using BlazorSyncfusionCrm.Client
@ -11,4 +12,8 @@
@using Syncfusion.Blazor.Navigations @using Syncfusion.Blazor.Navigations
@using Syncfusion.Blazor.Buttons @using Syncfusion.Blazor.Buttons
@using Syncfusion.Blazor.Grids @using Syncfusion.Blazor.Grids
@using Syncfusion.Blazor.Inputs
@using Syncfusion.Blazor.Calendars
@using Syncfusion.Blazor.Notifications
@using Syncfusion.Blazor.Popups

View File

@ -8,6 +8,11 @@ main {
margin: 12px; margin: 12px;
} }
.validation-message {
font-size: 12px !important;
font-family: system-ui;
}
h1:focus { h1:focus {
outline: none; outline: none;
} }

View File

@ -7,6 +7,7 @@
<base href="/" /> <base href="/" />
<link href="css/app.css" rel="stylesheet" /> <link href="css/app.css" rel="stylesheet" />
<link href="_content/Syncfusion.Blazor/styles/bootstrap5.css" rel="stylesheet" /> <link href="_content/Syncfusion.Blazor/styles/bootstrap5.css" rel="stylesheet" />
<link href="BlazorSyncfusionCrm.Client.styles.css" rel="stylesheet" />
<!-- If you add any scoped CSS files, uncomment the following to load them <!-- If you add any scoped CSS files, uncomment the following to load them
<link href="BlazorSyncfusionCrm.Client.styles.css" rel="stylesheet" /> --> <link href="BlazorSyncfusionCrm.Client.styles.css" rel="stylesheet" /> -->
</head> </head>

View File

@ -0,0 +1,87 @@
using BlazorSyncfusionCrm.Server.Data;
using BlazorSyncfusionCrm.Shared;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace BlazorSyncfusionCrm.Server.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class ContactsController : ControllerBase
{
private readonly DataContext _context;
public ContactsController(DataContext context)
{
_context = context;
}
[HttpGet]
public async Task<ActionResult<List<Contact>>> GetAllContacts()
{
return await _context.Contacts
.Where(c => !c.IsDeleted)
.ToListAsync();
}
[HttpGet("{id}")]
public async Task<ActionResult<Contact>> GetContactById(int id)
{
var result = await _context.Contacts.FindAsync(id);
if (result == null)
{
return NotFound("Contact not found.");
}
return result;
}
[HttpPost]
public async Task<ActionResult<Contact>> CreateContact(Contact contact)
{
_context.Contacts.Add(contact);
await _context.SaveChangesAsync();
return Ok(contact);
}
[HttpPut("{id}")]
public async Task<ActionResult<Contact>> UpdateContact(int id, Contact contact)
{
var dbContact = await _context.Contacts.FindAsync(id);
if (dbContact == null)
{
return NotFound("Contact not found.");
}
dbContact.FirstName = contact.FirstName;
dbContact.LastName = contact.LastName;
dbContact.NickName = contact.NickName;
dbContact.DateOfBirth = contact.DateOfBirth;
dbContact.Place = contact.Place;
dbContact.DateUpdated = DateTime.Now;
await _context.SaveChangesAsync();
return Ok(contact);
}
[HttpDelete("{id}")]
public async Task<ActionResult<List<Contact>>> DeleteContact(int id)
{
var dbContact = await _context.Contacts.FindAsync(id);
if (dbContact == null)
{
return NotFound("Contact not found.");
}
dbContact.IsDeleted = true;
dbContact.DateDeleted = DateTime.Now;
await _context.SaveChangesAsync();
return await GetAllContacts();
}
}
}

View File

@ -0,0 +1,33 @@
using BlazorSyncfusionCrm.Server.Data;
using BlazorSyncfusionCrm.Shared;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
namespace BlazorSyncfusionCrm.Server.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class NotesController : ControllerBase
{
private readonly DataContext _context;
public NotesController(DataContext context)
{
_context = context;
}
[HttpGet]
public async Task<ActionResult<List<Note>>> GetAllNotes()
{
return await _context.Notes
.Include(n => n.Contact)
.OrderByDescending(n => n.DateCreated)
.ToListAsync();
}
}
}

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
@ -12,6 +13,7 @@ namespace BlazorSyncfusionCrm.Shared
public int Id { get; set; } public int Id { get; set; }
public string FirstName { get; set; } = string.Empty; public string FirstName { get; set; } = string.Empty;
public string LastName { get; set; } = string.Empty; public string LastName { get; set; } = string.Empty;
[Required]
public string NickName { get; set; } = string.Empty; public string NickName { get; set; } = string.Empty;
public string Place { get; set; } = string.Empty; public string Place { get; set; } = string.Empty;
public bool IsDeleted { get; set; } public bool IsDeleted { get; set; }