Implemented Profile
This commit is contained in:
@@ -51,7 +51,7 @@
|
||||
JD
|
||||
</div>
|
||||
<div class="flex flex-col text-left leading-tight hidden sm:flex">
|
||||
<span class="text-[12px] font-semibold text-[#1f2a3a]">Jane Doe</span>
|
||||
<span class="text-[12px] font-semibold text-[#1f2a3a]">J. Mokoena</span>
|
||||
<span class="text-[11px] text-[#8a96a8]">Travel Bookings Admin</span>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
@@ -1,7 +1,276 @@
|
||||
@page "/profile"
|
||||
@rendermode InteractiveServer
|
||||
@using System
|
||||
@using System.Collections.Generic
|
||||
@using System.Linq
|
||||
@using System.Threading.Tasks
|
||||
|
||||
<h3>Profile</h3>
|
||||
<PageTitle>VIP Traveller Profile - J. Mokoena</PageTitle>
|
||||
|
||||
<div class="max-w-[1600px] mx-auto pb-8">
|
||||
<!-- Page Header -->
|
||||
<div class="flex flex-col sm:flex-row justify-between items-start sm:items-end mb-[22px] gap-3">
|
||||
<div>
|
||||
<h2 class="text-[22px] font-bold text-[#1f2a3a] tracking-tight outline-none focus:outline-none select-none" tabindex="-1">Traveller Profile</h2>
|
||||
<p class="text-[13px] text-[#5a6577] mt-1">Manage corporate travel credentials, frequent flyer integrations, active visas and personal preferences</p>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<span class="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-full text-xs font-semibold bg-[#e3f6ed] text-[#22a06b]">
|
||||
<span class="w-2 h-2 rounded-full bg-[#22a06b]"></span>
|
||||
VIP Executive Account Verified (Grade 1)
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@* Alert / Feedback Notification *@
|
||||
@if (!string.IsNullOrEmpty(_alertFeedback))
|
||||
{
|
||||
<div class="mb-6 p-4 bg-[#effaf3] border-l-4 border-[#22a06b] rounded-r-lg text-sm text-[#1b8054] flex items-center gap-2.5 shadow-xs animate-in fade-in duration-300">
|
||||
<svg class="w-5 h-5 text-[#22a06b] shrink-0" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
<span>@_alertFeedback</span>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="grid grid-cols-1 lg:grid-cols-[1fr_2fr] gap-6">
|
||||
|
||||
<!-- Left Column: Quick Profile Card & Stats -->
|
||||
<div class="space-y-6">
|
||||
<!-- 1. Avatar & Corporate details -->
|
||||
<div class="bg-white rounded-[10px] shadow-[0_1px_2px_rgba(15,23,42,.06)] border border-[#e4eaf2] p-6 text-center relative overflow-hidden">
|
||||
<div class="absolute top-0 left-0 right-0 h-2 bg-gradient-to-r from-[#003b71] to-[#00a3a1]"></div>
|
||||
|
||||
<div class="w-24 h-24 rounded-full bg-gradient-to-br from-[#003b71] to-[#00a3a1] text-white flex items-center justify-center font-bold text-3xl mx-auto mb-4 border-4 border-white shadow-md">
|
||||
JM
|
||||
</div>
|
||||
|
||||
<h3 class="text-lg font-bold text-[#1f2a3a]">Jabulani Mokoena</h3>
|
||||
<p class="text-xs font-semibold text-[#0066b3]">Executive Chief Director</p>
|
||||
<p class="text-[11px] text-[#8a96a8] mt-1">SAQA Corporate Strategy & Finance</p>
|
||||
|
||||
<div class="mt-4 pt-4 border-t border-[#e4eaf2] text-left space-y-2.5 text-xs">
|
||||
<div class="flex justify-between">
|
||||
<span class="text-[#8a96a8]">Email</span>
|
||||
<span class="font-semibold text-[#1f2a3a]">j.mokoena@saqa.co.za</span>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<span class="text-[#8a96a8]">Mobile</span>
|
||||
<span class="font-semibold text-[#1f2a3a]">+27 82 555 0192</span>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<span class="text-[#8a96a8]">Base Office</span>
|
||||
<span class="font-semibold text-[#1f2a3a]">Pretoria (HQ)</span>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<span class="text-[#8a96a8]">Cost Centre</span>
|
||||
<span class="font-semibold text-[#1f2a3a] font-mono text-[#0066b3]">CC-FIN-701</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button @onclick="@(() => TriggerProfileSync())" class="w-full mt-5 px-4 py-2 border border-[#0066b3] text-[#0066b3] hover:bg-[#e2eefb] font-bold text-xs rounded-lg transition-colors cursor-pointer">
|
||||
馃攧 Sync HR Profile Credentials
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- 2. Year-to-Date Travel Stats -->
|
||||
<div class="bg-white rounded-[10px] shadow-[0_1px_2px_rgba(15,23,42,.06)] border border-[#e4eaf2] p-5 text-left">
|
||||
<h3 class="text-xs font-bold text-[#1f2a3a] uppercase tracking-wider mb-3">YTD Corporate Travel Stats</h3>
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<div class="p-3 bg-[#fafcfe] border border-[#e4eaf2] rounded-lg text-center">
|
||||
<span class="block text-[10px] text-[#8a96a8] font-semibold uppercase">Flights</span>
|
||||
<span class="text-xl font-bold text-[#1f2a3a]">14</span>
|
||||
</div>
|
||||
<div class="p-3 bg-[#fafcfe] border border-[#e4eaf2] rounded-lg text-center">
|
||||
<span class="block text-[10px] text-[#8a96a8] font-semibold uppercase">Hotel Nights</span>
|
||||
<span class="text-xl font-bold text-[#1f2a3a]">12</span>
|
||||
</div>
|
||||
<div class="p-3 bg-[#fafcfe] border border-[#e4eaf2] rounded-lg text-center">
|
||||
<span class="block text-[10px] text-[#8a96a8] font-semibold uppercase">Carbon Footprint</span>
|
||||
<span class="text-xs font-bold text-emerald-600">4.8 Tonnes</span>
|
||||
</div>
|
||||
<div class="p-3 bg-[#fafcfe] border border-[#e4eaf2] rounded-lg text-center">
|
||||
<span class="block text-[10px] text-[#8a96a8] font-semibold uppercase">Billed to Lodge</span>
|
||||
<span class="text-xs font-bold text-[#0066b3]">R 245,390</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Right Column: Interactive Preferences, Active Visas, loyalty Programs -->
|
||||
<div class="space-y-6">
|
||||
|
||||
<!-- 1. Personal Travel Preferences Form -->
|
||||
<div class="bg-white rounded-[10px] shadow-[0_1px_2px_rgba(15,23,42,.06)] border border-[#e4eaf2] p-6 text-left">
|
||||
<div class="flex justify-between items-center mb-4">
|
||||
<div>
|
||||
<h3 class="text-[15px] font-bold text-[#1f2a3a]">Traveller Preferences</h3>
|
||||
<p class="text-[12px] text-[#8a96a8] mt-0.5">Automated booking defaults locked into the GDS profile parser</p>
|
||||
</div>
|
||||
<span class="bg-[#e2eefb] text-[#0066b3] px-2.5 py-[3px] rounded-full text-[11px] font-semibold">Active</span>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 text-xs">
|
||||
<div>
|
||||
<label class="block text-[10px] font-bold uppercase text-[#8a96a8] mb-1">Default Flight Seating</label>
|
||||
<select @bind="_seatPreference" class="w-full px-3 py-2 border border-[#c8d3e1] rounded-lg bg-white text-[#1f2a3a] outline-none focus:border-[#0066b3]">
|
||||
<option value="Window">Window Seat (First choice)</option>
|
||||
<option value="Aisle">Aisle Seat</option>
|
||||
<option value="Exit Row">Extra Legroom / Exit Row</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="block text-[10px] font-bold uppercase text-[#8a96a8] mb-1">Dietary Requirement</label>
|
||||
<select @bind="_dietaryPreference" class="w-full px-3 py-2 border border-[#c8d3e1] rounded-lg bg-white text-[#1f2a3a] outline-none focus:border-[#0066b3]">
|
||||
<option value="Standard">Standard Meal</option>
|
||||
<option value="Vegetarian">Hindu Vegetarian (AVML)</option>
|
||||
<option value="Halal">Halal (MOML)</option>
|
||||
<option value="Kosher">Kosher (KSML)</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="block text-[10px] font-bold uppercase text-[#8a96a8] mb-1">Hotel Bed Type Preference</label>
|
||||
<select @bind="_bedPreference" class="w-full px-3 py-2 border border-[#c8d3e1] rounded-lg bg-white text-[#1f2a3a] outline-none focus:border-[#0066b3]">
|
||||
<option value="King">King size bed</option>
|
||||
<option value="Twin">Two double beds (Twin)</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="block text-[10px] font-bold uppercase text-[#8a96a8] mb-1">Default Car Group</label>
|
||||
<select @bind="_carPreference" class="w-full px-3 py-2 border border-[#c8d3e1] rounded-lg bg-white text-[#1f2a3a] outline-none focus:border-[#0066b3]">
|
||||
<option value="SUV">Group D - Midsize SUV</option>
|
||||
<option value="Sedan">Group C - Fullsize Sedan</option>
|
||||
<option value="Luxury">Group G - Elite / Luxury</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-4 pt-4 border-t border-[#e4eaf2] flex justify-end">
|
||||
<button @onclick="@(() => SavePreferences())" class="px-4 py-2 bg-[#0066b3] text-white font-bold text-xs rounded-lg hover:bg-[#003b71] cursor-pointer shadow-xs">
|
||||
Save Preferences
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 2. Active Passport & Visas -->
|
||||
<div class="bg-white rounded-[10px] shadow-[0_1px_2px_rgba(15,23,42,.06)] border border-[#e4eaf2] p-6 text-left">
|
||||
<div class="flex justify-between items-center mb-4">
|
||||
<div>
|
||||
<h3 class="text-[15px] font-bold text-[#1f2a3a]">Passport & Active Visas</h3>
|
||||
<p class="text-[12px] text-[#8a96a8] mt-0.5">Scanned credentials checked against immigration guidelines during visa-booking workflow</p>
|
||||
</div>
|
||||
<span class="text-xs text-[#0066b3] font-bold flex items-center gap-1">
|
||||
馃攽 Encypted Vault
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="space-y-3">
|
||||
<!-- Passport -->
|
||||
<div class="p-3.5 border border-[#e4eaf2] rounded-lg bg-gradient-to-r from-white to-[#fafcfe] flex justify-between items-center text-xs">
|
||||
<div>
|
||||
<span class="block font-bold text-[#1f2a3a]">South African Passport</span>
|
||||
<span class="text-[11px] font-mono text-[#8a96a8]">Doc No: AA9923812 路 Expires: 12 Jan 2031</span>
|
||||
</div>
|
||||
<span class="text-[10px] font-bold text-[#22a06b] bg-[#e3f6ed] px-2 py-0.5 rounded">Primary</span>
|
||||
</div>
|
||||
|
||||
<!-- Visa 1 -->
|
||||
<div class="p-3.5 border border-[#e4eaf2] rounded-lg bg-gradient-to-r from-white to-[#fafcfe] flex justify-between items-center text-xs">
|
||||
<div>
|
||||
<span class="block font-bold text-[#1f2a3a]">United Kingdom Standard Visitor Visa</span>
|
||||
<span class="text-[11px] font-mono text-[#8a96a8]">Ref: UKV-882190B 路 Multi-Entry 路 Expires: 05 Jun 2028</span>
|
||||
</div>
|
||||
<span class="text-[10px] font-bold text-[#22a06b] bg-[#e3f6ed] px-2 py-0.5 rounded">Valid</span>
|
||||
</div>
|
||||
|
||||
<!-- Visa 2 -->
|
||||
<div class="p-3.5 border border-[#e4eaf2] rounded-lg bg-gradient-to-r from-white to-[#fafcfe] flex justify-between items-center text-xs">
|
||||
<div>
|
||||
<span class="block font-bold text-[#1f2a3a]">United States Business Visa (B1/B2)</span>
|
||||
<span class="text-[11px] font-mono text-[#8a96a8]">Ref: USV-0992381 路 10-Year Multi 路 Expires: 19 Oct 2031</span>
|
||||
</div>
|
||||
<span class="text-[10px] font-bold text-[#22a06b] bg-[#e3f6ed] px-2 py-0.5 rounded">Valid</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 3. Frequent Flyer & Loyalty Programs -->
|
||||
<div class="bg-white rounded-[10px] shadow-[0_1px_2px_rgba(15,23,42,.06)] border border-[#e4eaf2] p-6 text-left">
|
||||
<div class="flex justify-between items-center mb-4">
|
||||
<div>
|
||||
<h3 class="text-[15px] font-bold text-[#1f2a3a]">Frequent Flyer Integrations</h3>
|
||||
<p class="text-[12px] text-[#8a96a8] mt-0.5">Direct GDS link to auto-claim points on personal frequent flyer portfolios</p>
|
||||
</div>
|
||||
<button @onclick="@(() => LinkNewProgram())" class="px-2.5 py-1 bg-white border border-[#e4eaf2] text-[11px] text-[#5a6577] hover:text-[#1f2a3a] font-semibold rounded-lg transition-colors cursor-pointer">
|
||||
+ Add Program
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-3">
|
||||
@foreach (var program in _loyaltyPrograms)
|
||||
{
|
||||
<div class="p-3.5 border border-[#e4eaf2] rounded-lg bg-[#f4f7fb] text-left">
|
||||
<span class="block text-[10px] text-[#8a96a8] font-bold uppercase">@program.Airline</span>
|
||||
<span class="block text-xs font-bold text-[#1f2a3a] mt-1 truncate">@program.Level Tier</span>
|
||||
<span class="block text-[10px] font-mono text-[#5a6577] mt-0.5">No: @program.Number</span>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
private string _alertFeedback = string.Empty;
|
||||
|
||||
// Traveller Preference Bindings
|
||||
private string _seatPreference = "Window";
|
||||
private string _dietaryPreference = "Vegetarian";
|
||||
private string _bedPreference = "King";
|
||||
private string _carPreference = "SUV";
|
||||
|
||||
// Loyalty Program Class
|
||||
public class LoyaltyProgram
|
||||
{
|
||||
public string Airline { get; set; } = string.Empty;
|
||||
public string Level { get; set; } = string.Empty;
|
||||
public string Number { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
private List<LoyaltyProgram> _loyaltyPrograms = new()
|
||||
{
|
||||
new() { Airline = "South African Airways", Level = "SAA Voyager Gold", Number = "VS-992381" },
|
||||
new() { Airline = "British Airways", Level = "Executive Club Silver", Number = "BA-882019" },
|
||||
new() { Airline = "Emirates Airlines", Level = "Skywards Silver", Number = "EK-110294" }
|
||||
};
|
||||
|
||||
private void TriggerProfileSync()
|
||||
{
|
||||
_alertFeedback = "Securing OAuth handshake... Traveller biographical credentials, frequent flyer balances and visa records successfully synchronized with the central SAQA HR Portal!";
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
private void SavePreferences()
|
||||
{
|
||||
_alertFeedback = $"Traveller preferences successfully updated in the GDS master profile! Future bookings will lock in seating: {_seatPreference}, dietary: {_dietaryPreference}, room: {_bedPreference} bed, and car preference.";
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
private void LinkNewProgram()
|
||||
{
|
||||
_loyaltyPrograms.Add(new LoyaltyProgram
|
||||
{
|
||||
Airline = "Qatar Airways",
|
||||
Level = "Privilege Club Gold",
|
||||
Number = "QR-" + new Random().Next(100000, 999999)
|
||||
});
|
||||
_alertFeedback = "New frequent flyer integration added successfully!";
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+5
@@ -3018,6 +3018,11 @@
|
||||
grid-template-columns: 1fr 1fr 1fr 1fr auto;
|
||||
}
|
||||
}
|
||||
.lg\:grid-cols-\[1fr_2fr\] {
|
||||
@media (width >= 64rem) {
|
||||
grid-template-columns: 1fr 2fr;
|
||||
}
|
||||
}
|
||||
.lg\:grid-cols-\[2fr_1fr\] {
|
||||
@media (width >= 64rem) {
|
||||
grid-template-columns: 2fr 1fr;
|
||||
|
||||
Reference in New Issue
Block a user