7d8a8478ff
- Updated CustomerPlanService to replace references to PlaceRepo with FacilityRepository for managing customer plans and associated facilities. - Removed PlaceService and its related methods, consolidating functionality into FacilityService. - Added RfidTagService for managing RFID tags, including methods for creating, updating, and setting statuses of tags. - Updated TenantDbContext to include new DbSet for RfidTags and CustomerPlanFacilities, and adjusted model configurations accordingly. - Enhanced FacilityService to support new booking modes and validation for facility creation and updates.
87 lines
4.7 KiB
C#
87 lines
4.7 KiB
C#
using Fitness_core_BE.DTOs.Booking;
|
|
using System.Net;
|
|
|
|
namespace Fitness_core_BE.Helpers
|
|
{
|
|
// Minimal, dependency-free HTML for the public booking confirmation page (BookingController.
|
|
// ViewBooking). No admin dashboard or mobile app exists yet for this to link into instead --
|
|
// this is a self-contained page so "share the booking link" already works today.
|
|
public static class BookingViewHtml
|
|
{
|
|
public static string Render(BookingDto booking)
|
|
{
|
|
var who = booking.IsGuest ? Encode(booking.GuestName) : "Member booking";
|
|
var when = $"{booking.StartTime:dddd, dd MMM yyyy}, {booking.StartTime:h:mm tt} - {booking.EndTime:h:mm tt}";
|
|
|
|
var statusColor = booking.Status switch
|
|
{
|
|
"CheckedIn" => "#16a34a",
|
|
"Cancelled" => "#dc2626",
|
|
"NoShow" => "#dc2626",
|
|
_ => "#2563eb"
|
|
};
|
|
|
|
var otpBlock = !string.IsNullOrEmpty(booking.OtpCode)
|
|
? $$"""
|
|
<div class="otp-box">
|
|
<div class="otp-label">Show this code at the door</div>
|
|
<div class="otp-code">{{Encode(booking.OtpCode)}}</div>
|
|
</div>
|
|
"""
|
|
: booking.OtpVerified
|
|
? "<p class=\"muted\">Checked in -- code already used.</p>"
|
|
: "";
|
|
|
|
return $$"""
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
<title>Booking Confirmation - Vijaya Sport Club</title>
|
|
<style>
|
|
body { font-family: -apple-system, Segoe UI, Roboto, Arial, sans-serif; background: #f3f4f6; margin: 0; padding: 24px 16px; color: #111827; }
|
|
.card { max-width: 420px; margin: 0 auto; background: #fff; border-radius: 12px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); overflow: hidden; }
|
|
.header { background: #0f172a; color: #fff; padding: 20px; }
|
|
.header h1 { margin: 0; font-size: 18px; }
|
|
.body { padding: 20px; }
|
|
.row { display: flex; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid #f1f5f9; }
|
|
.row .label { color: #6b7280; font-size: 13px; }
|
|
.row .value { font-weight: 600; font-size: 13px; text-align: right; }
|
|
.status { display: inline-block; padding: 3px 10px; border-radius: 999px; color: #fff; font-size: 12px; font-weight: 600; background: {{statusColor}}; }
|
|
.otp-box { margin-top: 16px; text-align: center; background: #f8fafc; border: 1px dashed #cbd5e1; border-radius: 8px; padding: 16px; }
|
|
.otp-label { font-size: 12px; color: #6b7280; margin-bottom: 6px; }
|
|
.otp-code { font-size: 32px; font-weight: 700; letter-spacing: 6px; color: #0f172a; }
|
|
.muted { color: #6b7280; font-size: 13px; text-align: center; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="card">
|
|
<div class="header"><h1>Vijaya Sport Club</h1></div>
|
|
<div class="body">
|
|
<div class="row"><span class="label">Facility</span><span class="value">{{Encode(booking.FacilityName)}}</span></div>
|
|
<div class="row"><span class="label">Session</span><span class="value">{{Encode(when)}}</span></div>
|
|
<div class="row"><span class="label">Booked for</span><span class="value">{{who}}</span></div>
|
|
<div class="row"><span class="label">Payment</span><span class="value">{{Encode(booking.PaymentStatus)}}</span></div>
|
|
<div class="row"><span class="label">Status</span><span class="value"><span class="status">{{Encode(booking.Status)}}</span></span></div>
|
|
{{otpBlock}}
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|
|
""";
|
|
}
|
|
|
|
public static string NotFound() => """
|
|
<!DOCTYPE html>
|
|
<html><head><meta charset="utf-8" /><title>Booking not found</title></head>
|
|
<body style="font-family: sans-serif; text-align: center; padding: 60px 20px; color: #6b7280;">
|
|
<h2>Booking not found</h2>
|
|
<p>This link may have expired or the booking may have been cancelled.</p>
|
|
</body></html>
|
|
""";
|
|
|
|
private static string Encode(string? value) => WebUtility.HtmlEncode(value ?? "");
|
|
}
|
|
}
|