A component is a reusable part of the UI, created using a .razor file.
Hello Blazor
Welcome to my application.
Every component can contain HTML, C# logic, and event handlers.
Examples: Navbar, Login form, Product list, Dashboard
- Data Binding Data binding connects UI elements with C# variables.
<input @bind="name" /> <p>Your name: @name</p> @code { private string name = ""; } Event Handling
Handles user actions such as clicks and form submissions.
razor
<button @onclick="Increment">Click</button> <p>Count: @count</p> @code { private int count; private void Increment() { count++; } } Front-End ├── Components/ │ └── Admin/ │ ├── GymCard.razor │ └── GymForm.razor │ └── Pages/ └── Admin/ └── ManageGyms.razor ==================================================================== GymForm.razor @using Microsoft.AspNetCore.Components.Forms @using System.ComponentModel.DataAnnotations <EditForm Model="@Model" OnValidSubmit="@SubmitAsync"> <DataAnnotationsValidator /> <ValidationSummary class="text-danger mb-3" /> <div class="row g-3"> <div class="col-md-6"> <label class="form-label">Gym Name</label> <InputText class="form-control" @bind-Value="Model.GymName" /> <ValidationMessage For="@(() => Model.GymName)" /> </div> <div class="col-md-6"> <label class="form-label">City</label> <InputText class="form-control" @bind-Value="Model.CityName" /> <ValidationMessage For="@(() => Model.CityName)" /> </div> <div class="col-12"> <label class="form-label">Address</label> <InputText class="form-control" @bind-Value="Model.Address" /> <ValidationMessage For="@(() => Model.Address)" /> </div> <div class="col-md-6"> <label class="form-label">Phone</label> <InputText class="form-control" @bind-Value="Model.Phone" /> <ValidationMessage For="@(() => Model.Phone)" /> </div> <div class="col-md-6"> <label class="form-label">Email</label> <InputText class="form-control" @bind-Value="Model.Email" /> <ValidationMessage For="@(() => Model.Email)" /> </div> <div class="col-md-6"> <label class="form-label">Opening Time</label> <InputText type="time" class="form-control" @bind-Value="Model.OpeningTime" /> <ValidationMessage For="@(() => Model.OpeningTime)" /> </div> <div class="col-md-6"> <label class="form-label">Closing Time</label> <InputText type="time" class="form-control" @bind-Value="Model.ClosingTime" /> <ValidationMessage For="@(() => Model.ClosingTime)" /> </div> <div class="col-md-6"> <label class="form-label">Total Class Capacity</label> <InputNumber class="form-control" @bind-Value="Model.TotalClassCapacity" /> <ValidationMessage For="@(() => Model.TotalClassCapacity)" /> </div> <div class="col-md-6"> <label class="form-label">Status</label> <InputSelect class="form-select" @bind-Value="Model.Status"> <option value="Active">Active</option> <option value="Inactive">Inactive</option> </InputSelect> <ValidationMessage For="@(() => Model.Status)" /> </div> <div class="col-md-6"> <div class="form-check"> <InputCheckbox class="form-check-input" @bind-Value="Model.LockerFacility" /> <label class="form-check-label"> Locker facility available </label> </div> </div> <div class="col-md-6"> <div class="form-check"> <InputCheckbox class="form-check-input" @bind-Value="Model.ParkingAvailable" /> <label class="form-check-label"> Parking available </label> </div> </div> </div> <div class="d-flex justify-content-end gap-2 mt-4"> <button type="button" class="btn btn-outline-secondary" disabled="@IsSaving" @onclick="CancelAsync"> Cancel </button> <button type="submit" class="btn btn-primary" disabled="@IsSaving"> @if (IsSaving) { <span class="spinner-border spinner-border-sm me-2"></span> } @(IsEditMode ? "Update Gym" : "Save Gym") </button> </div> </EditForm> @code { [Parameter, EditorRequired] public ManageGyms.GymFormModel Model { get; set; } = default!; [Parameter] public bool IsEditMode { get; set; } [Parameter] public bool IsSaving { get; set; } [Parameter] public EventCallback OnValidSubmit { get; set; } [Parameter] public EventCallback OnCancel { get; set; } private Task SubmitAsync() => OnValidSubmit.InvokeAsync(); private Task CancelAsync() => OnCancel.InvokeAsync(); } ========================================================================== GymCard.razor <div class="card gym-card h-100 shadow-sm border-0"> <div class="card-header bg-white border-0 pt-3"> <div class="d-flex justify-content-between gap-2"> <div> <h5 class="fw-bold mb-1">@GymName</h5> <div class="text-muted small"> <i class="bi bi-geo-alt me-1"> @Display(CityName) </div> </div> <span class="badge @(IsActive ? "text-bg-success" : "text-bg-secondary")"> @Status </span> </div> </div> <div class="card-body"> <div class="gym-detail"> <i class="bi bi-geo-alt-fill"> <span>@Display(Address)</span> </div> <div class="gym-detail"> <i class="bi bi-telephone-fill"> <span>@Display(Phone)</span> </div> <div class="gym-detail"> <i class="bi bi-envelope-fill"> <span class="gym-email">@Display(Email)</span> </div> <div class="gym-detail"> <i class="bi bi-clock-fill"> <span> @OpeningTime.ToString(@"hh\:mm") – @ClosingTime.ToString(@"hh\:mm") </span> </div> <div class="gym-detail"> <i class="bi bi-people-fill"> <span>Class capacity: @TotalClassCapacity</span> </div> <div class="gym-detail"> <i class="bi bi-lock-fill"> <span>Locker: @(LockerFacility ? "Available" : "Not available")</span> </div> <div class="gym-detail"> <i class="bi bi-car-front-fill"> <span>Parking: @(ParkingAvailable ? "Available" : "Not available")</span> </div> </div> <div class="card-footer bg-white border-0 pb-3"> <div class="d-flex flex-wrap gap-2"> <button type="button" class="btn btn-primary btn-sm flex-fill" @onclick="() => OnViewPlans.InvokeAsync(Id)"> <i class="bi bi-card-list me-1"> View Plans </button> <button type="button" class="btn btn-outline-secondary btn-sm" @onclick="() => OnEdit.InvokeAsync(Id)"> <i class="bi bi-pencil-square me-1"> Edit </button> <button type="button" class="btn btn-outline-danger btn-sm" @onclick="() => OnDelete.InvokeAsync(Id)"> <i class="bi bi-trash me-1"> Delete </button> </div> </div> </div> <style> .gym-card { border-radius: 12px; transition: transform .2s ease; } .gym-card:hover { transform: translateY(-3px); } .gym-detail { display: flex; align-items: flex-start; gap: 10px; margin-bottom: 12px; overflow-wrap: anywhere; } .gym-detail > i { color: #0d6efd; min-width: 18px; margin-top: 3px; } .gym-email { overflow-wrap: anywhere; } @code { [Parameter] public Guid Id { get; set; } [Parameter] public string GymName { get; set; } = ""; [Parameter] public string Address { get; set; } = ""; [Parameter] public string CityName { get; set; } = ""; [Parameter] public string Phone { get; set; } = ""; [Parameter] public string Email { get; set; } = ""; [Parameter] public TimeSpan OpeningTime { get; set; } [Parameter] public TimeSpan ClosingTime { get; set; } [Parameter] public int TotalClassCapacity { get; set; } [Parameter] public bool LockerFacility { get; set; } [Parameter] public bool ParkingAvailable { get; set; } [Parameter] public string Status { get; set; } = "Active"; [Parameter] public EventCallback<Guid> OnEdit { get; set; } [Parameter] public EventCallback<Guid> OnDelete { get; set; } [Parameter] public EventCallback<Guid> OnViewPlans { get; set; } private bool IsActive => string.Equals(Status, "Active", StringComparison.OrdinalIgnoreCase); private static string Display(string? value) => string.IsNullOrWhiteSpace(value) ? "Not provided" : value; } ================================================================ ManageGyms.razor (Admin) @page "/admin/gyms" @using System.Net.Http.Json @using System.ComponentModel.DataAnnotations @using Microsoft.AspNetCore.Authorization @usingSource:https://dev.to/elio_gabriel/components-2km9PreviousThere Are Four GPUs Called RTX 6000. Here's How I Make Sure I Rent the 96 GB OneNextFree tiers die quietly — so I verify every link in my directory, every week
Related posts
New York Times and other outlets sue web browser Brave over alleged content scraping
0TechCrunch
Web host Squarespace lays off 19% of its employees
0TechCrunch
Feature Flag Comparison: Reconstructing Silent Imports With Free and Paid Tools
0dev.to
I built K-Hangang: a peaceful 3D walk along Seoul's Han River
0dev.to
Building a Developer Community Beyond Just Coding
0dev.to
A Tenant Leak Does Not Throw an Error. It Just Returns the Wrong Rows.
0dev.to