128 lines
5.1 KiB
C#
128 lines
5.1 KiB
C#
using Inspectron.Epson.PrintServer.ConfigurationSources;
|
|
|
|
namespace EpsonPrintService;
|
|
|
|
public static class HtmlPageBuilder
|
|
{
|
|
public static string BuildConfigPage(
|
|
EpsonPrintServiceConfiguration? currentConfig,
|
|
bool printServerRunning,
|
|
UsbKeyResult? usbResult,
|
|
string? errorMessage = null)
|
|
{
|
|
var statusColor = printServerRunning ? "#2e7d32" : "#e65100";
|
|
var statusText = printServerRunning ? "Running" : "Not Configured";
|
|
|
|
return $@"<!DOCTYPE html>
|
|
<html lang=""en"">
|
|
<head>
|
|
<meta charset=""UTF-8"">
|
|
<meta name=""viewport"" content=""width=device-width, initial-scale=1.0"">
|
|
<title>Epson Print Server</title>
|
|
<style>
|
|
body {{ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; max-width: 600px; margin: 40px auto; padding: 0 20px; background: #f5f5f5; color: #333; }}
|
|
h1 {{ font-size: 1.4em; }}
|
|
.card {{ background: #fff; border-radius: 8px; padding: 20px; margin: 16px 0; box-shadow: 0 1px 3px rgba(0,0,0,0.12); }}
|
|
.status {{ display: inline-block; padding: 4px 12px; border-radius: 12px; color: #fff; font-weight: bold; font-size: 0.9em; background: {statusColor}; }}
|
|
.info {{ color: #666; font-size: 0.9em; }}
|
|
.info strong {{ color: #333; }}
|
|
.error {{ background: #ffebee; border-left: 4px solid #c62828; padding: 12px 16px; border-radius: 4px; margin: 12px 0; color: #c62828; }}
|
|
.usb {{ background: #e3f2fd; border-left: 4px solid #1565c0; padding: 12px 16px; border-radius: 4px; margin: 12px 0; }}
|
|
.usb strong {{ color: #1565c0; }}
|
|
.btn {{ display: inline-block; padding: 10px 24px; border: none; border-radius: 6px; font-size: 1em; cursor: pointer; text-decoration: none; color: #fff; }}
|
|
.btn-primary {{ background: #1565c0; }}
|
|
.btn-primary:hover {{ background: #0d47a1; }}
|
|
.btn-secondary {{ background: #757575; }}
|
|
.btn-secondary:hover {{ background: #616161; }}
|
|
.actions {{ margin-top: 16px; display: flex; gap: 10px; align-items: center; }}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<h1>Epson Print Server</h1>
|
|
|
|
<div class=""card"">
|
|
<p>Status: <span class=""status"">{statusText}</span></p>
|
|
{(currentConfig != null ? $@"
|
|
<div class=""info"">
|
|
<p><strong>Restaurant ID:</strong> {Escape(currentConfig.RestaurantId)}</p>
|
|
<p><strong>API URL:</strong> {Escape(currentConfig.ApiUrl ?? "(not set)")}</p>
|
|
</div>" : "")}
|
|
</div>
|
|
|
|
{(errorMessage != null ? $@"<div class=""error"">{Escape(errorMessage)}</div>" : "")}
|
|
|
|
{BuildUsbSection(usbResult)}
|
|
|
|
<div class=""actions"">
|
|
<a href=""/"" class=""btn btn-secondary"">Refresh</a>
|
|
</div>
|
|
|
|
</body>
|
|
</html>";
|
|
}
|
|
|
|
private static string BuildUsbSection(UsbKeyResult? usbResult)
|
|
{
|
|
if (usbResult == null)
|
|
return "";
|
|
|
|
if (usbResult.Error != null && !usbResult.Found)
|
|
return $@"<div class=""card""><p class=""info"">{Escape(usbResult.Error)}</p></div>";
|
|
|
|
if (!usbResult.Found)
|
|
return @"<div class=""card""><p class=""info"">No USB drive with <strong>print_server_key.txt</strong> found. Insert a USB drive and press Refresh.</p></div>";
|
|
|
|
if (usbResult.Error != null)
|
|
return $@"<div class=""error"">USB key found but invalid: {Escape(usbResult.Error)}</div>";
|
|
|
|
return $@"
|
|
<div class=""card"">
|
|
<div class=""usb"">
|
|
<strong>USB Key Found</strong>
|
|
<p class=""info""><strong>Restaurant ID:</strong> {Escape(usbResult.DecodedRestaurantId ?? "?")}</p>
|
|
<p class=""info""><strong>API URL:</strong> {Escape(usbResult.DecodedApiUrl ?? "?")}</p>
|
|
</div>
|
|
<form method=""POST"" action=""/update-key"" style=""margin-top: 12px;"">
|
|
<button type=""submit"" class=""btn btn-primary"">Update Key</button>
|
|
</form>
|
|
</div>";
|
|
}
|
|
|
|
public static string BuildSuccessPage(EpsonPrintServiceConfiguration newConfig)
|
|
{
|
|
return $@"<!DOCTYPE html>
|
|
<html lang=""en"">
|
|
<head>
|
|
<meta charset=""UTF-8"">
|
|
<meta name=""viewport"" content=""width=device-width, initial-scale=1.0"">
|
|
<meta http-equiv=""refresh"" content=""10;url=/"">
|
|
<title>Configuration Updated</title>
|
|
<style>
|
|
body {{ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; max-width: 600px; margin: 40px auto; padding: 0 20px; background: #f5f5f5; color: #333; }}
|
|
h1 {{ font-size: 1.4em; color: #2e7d32; }}
|
|
.card {{ background: #fff; border-radius: 8px; padding: 20px; margin: 16px 0; box-shadow: 0 1px 3px rgba(0,0,0,0.12); }}
|
|
.success {{ background: #e8f5e9; border-left: 4px solid #2e7d32; padding: 12px 16px; border-radius: 4px; }}
|
|
.info {{ color: #666; font-size: 0.9em; }}
|
|
.info strong {{ color: #333; }}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<h1>Configuration Updated!</h1>
|
|
<div class=""card"">
|
|
<div class=""success"">
|
|
<p>The configuration has been saved. The service will restart automatically.</p>
|
|
</div>
|
|
<div class=""info"" style=""margin-top: 12px;"">
|
|
<p><strong>Restaurant ID:</strong> {Escape(newConfig.RestaurantId)}</p>
|
|
<p><strong>API URL:</strong> {Escape(newConfig.ApiUrl ?? "(not set)")}</p>
|
|
</div>
|
|
<p class=""info"" style=""margin-top: 12px;"">This page will refresh in 10 seconds...</p>
|
|
</div>
|
|
</body>
|
|
</html>";
|
|
}
|
|
|
|
private static string Escape(string value) =>
|
|
System.Net.WebUtility.HtmlEncode(value);
|
|
}
|