- Add mobile-first modal design with full-screen layout and slide-up animation - Optimize touch targets to minimum 44px with proper spacing - Convert to single-column mobile layout stacking all form fields vertically - Replace Bootstrap datepicker with native HTML5 date input on mobile - Simplify tag selection with mobile-friendly chip input and touch targets - Default to Simple mode on mobile with clear mode toggle - Implement bottom sheet pattern with swipe-to-dismiss gesture - Add mobile-specific CSS with touch feedback and proper breakpoints - Implement progressive enhancement with mobile detection utilities 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
171 lines
12 KiB
Plaintext
171 lines
12 KiB
Plaintext
@using MotoVaultPro.Helper
|
|
@inject IConfigHelper config
|
|
@inject ITranslationHelper translator
|
|
@model GasRecordInputContainer
|
|
@{
|
|
var userConfig = config.GetUserConfig(User);
|
|
var useMPG = userConfig.UseMPG;
|
|
var useUKMPG = userConfig.UseUKMPG;
|
|
var userLanguage = userConfig.UserLanguage;
|
|
var useThreeDecimals = userConfig.UseThreeDecimalGasCost;
|
|
var useThreeDecimalsConsumption = userConfig.UseThreeDecimalGasConsumption;
|
|
var useKwh = Model.UseKwh;
|
|
var useHours = Model.UseHours;
|
|
var isNew = Model.GasRecord.Id == 0;
|
|
var useUnitFuelCost = userConfig.UseUnitForFuelCost;
|
|
var useSimpleFuelEntry = userConfig.UseSimpleFuelEntry;
|
|
string consumptionUnit;
|
|
string distanceUnit;
|
|
if (useKwh)
|
|
{
|
|
consumptionUnit = "kWh";
|
|
} else if (useUKMPG)
|
|
{
|
|
consumptionUnit = @translator.Translate(userLanguage, "liters");
|
|
}
|
|
else
|
|
{
|
|
consumptionUnit = useMPG ? @translator.Translate(userLanguage, "gallons") : @translator.Translate(userLanguage, "liters");
|
|
}
|
|
if (useHours)
|
|
{
|
|
distanceUnit = @translator.Translate(userLanguage, "hours");
|
|
}
|
|
else if (useUKMPG)
|
|
{
|
|
distanceUnit = @translator.Translate(userLanguage, "miles");
|
|
}
|
|
else
|
|
{
|
|
distanceUnit = useMPG ? @translator.Translate(userLanguage, "miles") : @translator.Translate(userLanguage, "kilometers");
|
|
}
|
|
}
|
|
<div class="modal-header">
|
|
<div class="d-flex justify-content-between align-items-center w-100">
|
|
<h5 class="modal-title">@(isNew ? translator.Translate(userLanguage, "Add New Gas Record") : translator.Translate(userLanguage, "Edit Gas Record"))<small style="display:none; @(isNew ? "" : "cursor:pointer;")" class="cached-banner ms-2 text-warning" onclick='@(isNew ? "" : $"showEditGasRecordModal({Model.GasRecord.Id}, true)" )'>@translator.Translate(userLanguage, "Unsaved Changes")</small></h5>
|
|
<div class="d-flex align-items-center">
|
|
<div class="form-check form-switch me-3">
|
|
<input class="form-check-input" type="checkbox" role="switch" id="fuelEntryModeToggle" @(useSimpleFuelEntry ? "checked" : "") onchange="toggleFuelEntryMode(this.checked)">
|
|
<label class="form-check-label" for="fuelEntryModeToggle">@translator.Translate(userLanguage, "Simple Mode")</label>
|
|
</div>
|
|
<button type="button" class="btn-close" onclick="hideAddGasRecordModal()" aria-label="Close"></button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal-body" onkeydown="handleEnter(this)">
|
|
<form>
|
|
<div class="form-group">
|
|
<div class="row">
|
|
<div class="col-md-6 col-12 mobile-single-column">
|
|
<input type="text" id="workAroundInput" style="height:0px; width:0px; display:none;">
|
|
<!-- Simple Mode Fields -->
|
|
<div id="simpleModeFields" style="@(useSimpleFuelEntry ? "" : "display:none;")">
|
|
<label for="gasRecordMileage">@($"{translator.Translate(userLanguage,"Odometer Reading")}({distanceUnit})")</label>
|
|
<div class="input-group">
|
|
<input type="number" inputmode="numeric" id="gasRecordMileage" class="form-control" placeholder="@translator.Translate(userLanguage,"Odometer reading when refueled")" value="@(isNew || Model.GasRecord.Mileage == default ? "" : Model.GasRecord.Mileage)">
|
|
@if (isNew)
|
|
{
|
|
<div class="input-group-text">
|
|
<button type="button" class="btn btn-sm btn-primary zero-y-padding" onclick="getLastOdometerReadingAndIncrement('gasRecordMileage')"><i class="bi bi-plus"></i></button>
|
|
</div>
|
|
}
|
|
</div>
|
|
<label for="gasRecordUnitCost">@($"{translator.Translate(userLanguage, "Cost Per")} {consumptionUnit}")</label>
|
|
<input type="text" inputmode="decimal" onkeydown="interceptDecimalKeys(event)" onkeyup="@(useThreeDecimals ? "fixDecimalInput(this, 3)" : "fixDecimalInput(this, 2)"); calculateTotalCost()" id="gasRecordUnitCost" class="form-control" placeholder="@($"{translator.Translate(userLanguage, "Price per")} {consumptionUnit}")" value="">
|
|
<label for="gasRecordGallons">@($"{translator.Translate(userLanguage, "Fuel Consumption")}({consumptionUnit})")</label>
|
|
<input type="text" inputmode="decimal" onkeydown="interceptDecimalKeys(event)" onkeyup="@(useThreeDecimalsConsumption ? "fixDecimalInput(this, 3)" : "fixDecimalInput(this, 2)"); calculateTotalCost()" id="gasRecordGallons" class="form-control" placeholder="@translator.Translate(userLanguage,"Amount of gas refueled")" value="@(isNew ? "" : Model.GasRecord.Gallons)">
|
|
<label for="gasRecordCost">@translator.Translate(userLanguage,"Total Cost") <small class="text-muted">(auto-calculated)</small></label>
|
|
<input type="text" inputmode="decimal" id="gasRecordCost" class="form-control" placeholder="@translator.Translate(userLanguage,"Total cost calculated automatically")" value="@(isNew ? "" : Model.GasRecord.Cost)" readonly>
|
|
<!-- Hidden fields for simple mode with default values -->
|
|
<input type="hidden" id="simpleGasRecordDate" value="@DateTime.Now.ToShortDateString()">
|
|
<input type="hidden" id="simpleGasIsFillToFull" value="true">
|
|
<input type="hidden" id="simpleGasIsMissed" value="false">
|
|
<input type="hidden" id="simpleGasRecordNotes" value="">
|
|
<input type="hidden" id="simpleGasRecordTag" value="">
|
|
</div>
|
|
<!-- Advanced Mode Fields -->
|
|
<div id="advancedModeFields" style="@(useSimpleFuelEntry ? "display:none;" : "")">
|
|
<label for="gasRecordDate">@translator.Translate(userLanguage,"Date")</label>
|
|
<div class="input-group">
|
|
<input type="text" id="gasRecordDate" placeholder="@translator.Translate(userLanguage,"Date refueled")" class="form-control" value="@Model.GasRecord.Date">
|
|
<span class="input-group-text"><i class="bi bi-calendar-event"></i></span>
|
|
</div>
|
|
<label for="gasRecordMileage">@($"{translator.Translate(userLanguage,"Odometer Reading")}({distanceUnit})")</label>
|
|
<div class="input-group">
|
|
<input type="number" inputmode="numeric" id="gasRecordMileage" class="form-control" placeholder="@translator.Translate(userLanguage,"Odometer reading when refueled")" value="@(isNew || Model.GasRecord.Mileage == default ? "" : Model.GasRecord.Mileage)">
|
|
@if (isNew)
|
|
{
|
|
<div class="input-group-text">
|
|
<button type="button" class="btn btn-sm btn-primary zero-y-padding" onclick="getLastOdometerReadingAndIncrement('gasRecordMileage')"><i class="bi bi-plus"></i></button>
|
|
</div>
|
|
}
|
|
</div>
|
|
<label for="gasRecordGallons">@($"{translator.Translate(userLanguage, "Fuel Consumption")}({consumptionUnit})")</label>
|
|
<input type="text" inputmode="decimal" onkeydown="interceptDecimalKeys(event)" onkeyup="@(useThreeDecimalsConsumption ? "fixDecimalInput(this, 3)" : "fixDecimalInput(this, 2)")" id="gasRecordGallons" class="form-control" placeholder="@translator.Translate(userLanguage,"Amount of gas refueled")" value="@(isNew ? "" : Model.GasRecord.Gallons)">
|
|
<div class="form-check form-switch">
|
|
<input class="form-check-input" type="checkbox" role="switch" id="gasIsFillToFull" checked="@Model.GasRecord.IsFillToFull">
|
|
<label class="form-check-label" for="gasIsFillToFull">@translator.Translate(userLanguage,"Is Filled To Full")</label>
|
|
</div>
|
|
<div class="form-check form-switch">
|
|
<input class="form-check-input" type="checkbox" role="switch" id="gasIsMissed" checked="@Model.GasRecord.MissedFuelUp">
|
|
<label class="form-check-label" for="gasIsMissed">@translator.Translate(userLanguage,"Missed Fuel Up(Skip MPG Calculation)")</label>
|
|
</div>
|
|
<label for="GasRecordCost">@translator.Translate(userLanguage,"Cost")</label>
|
|
@if (isNew)
|
|
{
|
|
<div class="input-group">
|
|
<input type="text" onkeydown="interceptDecimalKeys(event)" onkeyup="@(useThreeDecimals ? "fixDecimalInput(this, 3)" : "fixDecimalInput(this, 2)")" inputmode="decimal" id="gasRecordCost" class="form-control" placeholder="@translator.Translate(userLanguage,"Cost of gas refueled")" value="@(isNew ? "" : Model.GasRecord.Cost)">
|
|
<div class="input-group-text">
|
|
<select class="form-select form-select-sm" id="gasCostType">
|
|
<!option @(useUnitFuelCost ? "" : "selected") value="total">@translator.Translate(userLanguage,"Total")</!option>
|
|
<!option @(useUnitFuelCost ? "selected" : "") value="unit">@translator.Translate(userLanguage,"Unit")</!option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
} else
|
|
{
|
|
<input type="text" inputmode="decimal" onkeydown="interceptDecimalKeys(event)" onkeyup="@(useThreeDecimals ? "fixDecimalInput(this, 3)" : "fixDecimalInput(this, 2)")" id="gasRecordCost" class="form-control" placeholder="@translator.Translate(userLanguage,"Cost of gas refueled")" value="@(isNew ? "" : Model.GasRecord.Cost)">
|
|
}
|
|
<label for="gasRecordTag">@translator.Translate(userLanguage,"Tags(optional)")</label>
|
|
<select multiple class="form-select" id="gasRecordTag">
|
|
@foreach (string tag in Model.GasRecord.Tags)
|
|
{
|
|
<!option value="@tag">@tag</!option>
|
|
}
|
|
</select>
|
|
@await Html.PartialAsync("_ExtraField", Model.GasRecord.ExtraFields)
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6 col-12 mobile-single-column" id="secondColumnFields" style="@(useSimpleFuelEntry ? "display:none;" : "")">
|
|
<label for="gasRecordNotes">@translator.Translate(userLanguage,"Notes(optional)")<a class="link-underline link-underline-opacity-0" onclick="showLinks(this)"><i class="bi bi-markdown ms-2"></i></a></label>
|
|
<textarea id="gasRecordNotes" class="form-control" rows="5">@Model.GasRecord.Notes</textarea>
|
|
<div>
|
|
@await Html.PartialAsync("_UploadedFiles", Model.GasRecord.Files)
|
|
@await Html.PartialAsync("_FileUploader", Model.GasRecord.Files.Any())
|
|
</div>
|
|
<div id="filesPendingUpload"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
<div class="modal-footer">
|
|
@if (!isNew)
|
|
{
|
|
<button type="button" class="btn btn-danger" onclick="deleteGasRecord(@Model.GasRecord.Id)" style="margin-right:auto;">@translator.Translate(userLanguage,"Delete")</button>
|
|
}
|
|
<button type="button" class="btn btn-secondary" onclick="hideAddGasRecordModal()">@translator.Translate(userLanguage,"Cancel")</button>
|
|
@if (isNew)
|
|
{
|
|
<button type="button" class="btn btn-primary" onclick="saveGasRecordToVehicle()">@translator.Translate(userLanguage,"Add New Gas Record")</button>
|
|
}
|
|
else if (!isNew)
|
|
{
|
|
<button type="button" class="btn btn-primary" onclick="saveGasRecordToVehicle(true)">@translator.Translate(userLanguage,"Edit Gas Record")</button>
|
|
}
|
|
</div>
|
|
<script>
|
|
function getGasRecordModelData(){
|
|
return { id: @Model.GasRecord.Id}
|
|
}
|
|
</script> |