Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
0520dff
feat(web): landing page v2 — scroll story, green brand, Autopilot Mon…
okieselbach Jul 30, 2026
99c86d9
fix(web): landing feedback round — linear story timeline, honest exam…
okieselbach Jul 30, 2026
4c98384
feat(web): hero v3 — mission-control cockpit instead of single-sessio…
okieselbach Jul 30, 2026
6574163
feat(web): hero v4 — real portal screenshots instead of fabricated co…
okieselbach Jul 30, 2026
9db5f55
feat(web): hero v5 — clean dashboard, real-analysis terminal, refined…
okieselbach Jul 30, 2026
51f0ee7
fix(web): story act 3 — notification + one-click diagnostics instead …
okieselbach Jul 30, 2026
59236ef
feat(web): hero v6 — portal-first layout from approved design draft
okieselbach Jul 30, 2026
b0c481f
feat(web): get-started flow page, honest Teams card, calm buttons, li…
okieselbach Jul 30, 2026
13d2a10
feat(web): about/terms/privacy on the landing shell — no more sidebar…
okieselbach Jul 30, 2026
b414554
fix(web): landing navbar anchors root-anchored so they work from subp…
okieselbach Jul 30, 2026
85cd9d5
fix(web): calmer CTA green, about de-blued, public-page typography al…
okieselbach Jul 30, 2026
875aab0
fix(web): terms callouts on lp tokens — no more stray blue/amber banners
okieselbach Jul 30, 2026
7a996d5
fix(web): about tech stack — drop version numbers, fix stale SSR claim
okieselbach Jul 30, 2026
95c0b93
fix(web): terminal demo app renamed to Contoso CRM App
okieselbach Jul 30, 2026
0e22c7a
feat(web): analysis card confidence score, 40+ rules claim, final CTA…
okieselbach Jul 30, 2026
877e508
feat(web): portal brand aligned to landing, subtle Enterprise anchoring
okieselbach Jul 30, 2026
812862f
fix(web): final CTA right-aligned, get-started enterprise note "and m…
okieselbach Jul 30, 2026
e1d7f53
chore(web): social images refreshed to current hero claim and tagline
okieselbach Jul 30, 2026
c6b62fd
chore(web): social card wordmark single-color, matching the site
okieselbach Jul 30, 2026
961bfa6
feat(web): portal sidebar selection states green — brand-aligned like…
okieselbach Jul 30, 2026
cd1cf3c
fix(web): preview feedback round — dark-mode leak, alignment, renamed…
okieselbach Jul 30, 2026
e925ce4
feat(web): preview page on the new design + ?demo=1 review mode; foot…
okieselbach Jul 30, 2026
26c33f8
fix(web): preview page — prominent approval-pending badge, honest sta…
okieselbach Jul 30, 2026
4c22ee5
fix(web): about/terms/privacy cards flattened to the landing pinstrip…
okieselbach Jul 30, 2026
dc20897
feat(web): portal primary actions green — buttons, avatar, Progress P…
okieselbach Jul 30, 2026
a028019
feat(web): portal links and focus rings on brand green
okieselbach Jul 30, 2026
4be349f
fix(web): local dev sign-in repaired; progress portal brand accents g…
okieselbach Jul 30, 2026
ea891e6
fix(web): loading screens and remaining primary buttons on brand green
okieselbach Jul 30, 2026
e3e4b6f
fix(web): last blue interactive states green; monitoring headers wrap…
okieselbach Jul 30, 2026
3f203e8
fix(web): geo map dev crash — per-mount container key for Leaflet
okieselbach Jul 30, 2026
311b9d3
fix(web): form control accents (radios/checkboxes) green portal-wide
okieselbach Jul 30, 2026
967fb9e
fix(web): pin native form-control accent-color to brand green
okieselbach Jul 30, 2026
69ccc32
fix(web): progress portal icon inherits item color again
okieselbach Jul 30, 2026
1058e8c
fix(web): geo map root fix (react-leaflet 5) + readable dark muted text
okieselbach Jul 30, 2026
7dcff2c
fix(web): subtler dark hover surfaces — hovered rows stay readable
okieselbach Jul 30, 2026
aa0adcb
fix(web): GA/tenant notification rows dark-aware — opacity variants e…
okieselbach Jul 30, 2026
d6e048a
fix(web): notification row hover clearly distinguishable in dark mode
okieselbach Jul 30, 2026
3364e07
feat(web): one SegmentedControl for all range/group toggles
okieselbach Jul 30, 2026
44dff4e
fix(web): MCP usage sections use the shared SegmentedControl too
okieselbach Jul 30, 2026
f7c36c5
feat: clickable notification deep links in the bell dropdown
okieselbach Jul 30, 2026
9739d27
chore(web): npm overrides pin react-leaflet peer deps to installed react
okieselbach Jul 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ public async Task HandleNewTenantDomain_WhenDomainEmpty_ExtractsAndSaves()
_globalNotificationMock.Verify(x => x.CreateNotificationAsync(
"preview_signup", "New Preview Signup",
It.Is<string>(m => m.Contains(TenantId) && m.Contains("contoso.com") && m.Contains(Upn)),
null), Times.Once);
$"/admin/tenants/management?tenantId={TenantId}"), Times.Once);
}

[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,8 @@ internal async Task HandleNewTenantDomainAsync(
_ = _globalNotificationService.CreateNotificationAsync(
"preview_signup",
"New Preview Signup",
$"Tenant {tenantId} ({domain}), UPN: {upn}");
$"Tenant {tenantId} ({domain}), UPN: {upn}",
href: $"/admin/tenants/management?tenantId={Uri.EscapeDataString(tenantId)}");
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,8 @@ await _maintenanceRepo.LogAuditEntryAsync(
_ = _globalNotificationService.CreateNotificationAsync(
"diag_files_report",
"New Diag Files Report",
$"{userIdentifier} (Tenant: {request.TenantId})");
$"{userIdentifier} (Tenant: {request.TenantId})",
href: $"/admin/reports/session-reports?reportId={Uri.EscapeDataString(metadata.ReportId)}");

_logger.LogInformation("Diag-files report submitted: ReportId={ReportId}, By={User}",
metadata.ReportId, userIdentifier);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,8 @@ await _maintenanceRepo.LogAuditEntryAsync(
_ = _globalNotificationService.CreateNotificationAsync(
"session_report",
"New Session Report",
$"{userIdentifier} — Session {sessionId} (Tenant: {request.TenantId})");
$"{userIdentifier} — Session {sessionId} (Tenant: {request.TenantId})",
href: $"/admin/reports/session-reports?reportId={Uri.EscapeDataString(metadata.ReportId)}");

_logger.LogInformation("Session report submitted: ReportId={ReportId}, Session={SessionId}, By={User}",
metadata.ReportId, sessionId, userIdentifier);
Expand Down
4 changes: 2 additions & 2 deletions src/Web/autopilot-monitor-web/app/about/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ export const metadata: Metadata = {
"Autopilot Monitor overview",
],
openGraph: {
title: "About AutopilotMonitor – Real-Time Windows Autopilot Monitoring",
title: "About Autopilot Monitor – Real-Time Windows Autopilot Monitoring",
description:
"Free, open-source real-time monitoring and troubleshooting for Windows Autopilot enrollments. Track every phase, run analyze rules, and resolve issues faster — built by Oliver Kieselbach.",
url: `${SITE_URL}/about`,
},
twitter: {
title: "About AutopilotMonitor – Real-Time Windows Autopilot Monitoring",
title: "About Autopilot Monitor – Real-Time Windows Autopilot Monitoring",
description:
"Free, open-source real-time monitoring and troubleshooting for Windows Autopilot enrollments. Track every phase, run analyze rules, and resolve issues faster.",
},
Expand Down
95 changes: 56 additions & 39 deletions src/Web/autopilot-monitor-web/app/about/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Link from "next/link";
import { PublicPageHeader } from "../../components/PublicPageHeader";
import { LandingNavbar } from "../../components/landing/LandingNavbar";
import { SiteFooter } from "../../components/SiteFooter";
import { DOCS_URL } from "@/utils/config";

const FEATURES = [
Expand Down Expand Up @@ -47,25 +48,40 @@ const FEATURES = [
},
];

// Landing v2: one accent, no rainbow — every feature card uses the
// green brand accent regardless of its legacy color key.
const ACCENT_STYLE = {
bg: "bg-[var(--lp-accent-soft)]",
text: "text-[var(--lp-ink)]",
dot: "bg-[var(--lp-accent)]",
};
const colorMap: Record<string, { bg: string; text: string; dot: string }> = {
blue: { bg: "bg-blue-100", text: "text-blue-600", dot: "bg-blue-400" },
indigo: { bg: "bg-indigo-100", text: "text-indigo-600", dot: "bg-indigo-400" },
purple: { bg: "bg-purple-100", text: "text-purple-600", dot: "bg-purple-400" },
green: { bg: "bg-green-100", text: "text-green-600", dot: "bg-green-400" },
orange: { bg: "bg-orange-100", text: "text-orange-600", dot: "bg-orange-400" },
red: { bg: "bg-red-100", text: "text-red-600", dot: "bg-red-400" },
blue: ACCENT_STYLE,
indigo: ACCENT_STYLE,
purple: ACCENT_STYLE,
green: ACCENT_STYLE,
orange: ACCENT_STYLE,
red: ACCENT_STYLE,
};

export default function AboutPage() {
return (
<div className="min-h-screen bg-gray-50">
<PublicPageHeader title="About Autopilot Monitor" />
<div className="landing-v2 min-h-screen bg-[var(--lp-bg)]">
<LandingNavbar />
<header className="px-4 sm:px-6 lg:px-8 pt-14 sm:pt-16">
<div className="max-w-7xl mx-auto">
<p className="text-[11px] font-semibold uppercase tracking-[0.24em] text-[var(--lp-ink-faint)]">About</p>
<h1 className="mt-3 text-3xl sm:text-4xl font-bold tracking-tight text-[var(--lp-ink)]">
About Autopilot Monitor
</h1>
</div>
</header>

<main className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-10 space-y-10">
<main className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-10 space-y-10 text-[15px]">

{/* What is Autopilot Monitor */}
<section className="bg-white rounded-xl shadow-sm border border-gray-100 p-8">
<h2 className="text-2xl font-bold text-gray-900 mb-4">What is Autopilot Monitor?</h2>
<section className="bg-[var(--lp-surface)] border border-[var(--lp-line-soft)] rounded-xl p-8">
<h2 className="text-xl font-bold text-gray-900 mb-4">What is Autopilot Monitor?</h2>
<p className="text-gray-700 leading-relaxed mb-4">
<strong>Autopilot Monitor</strong> is a free, open-source, real-time monitoring and troubleshooting
platform for <strong>Windows Autopilot enrollments</strong> managed through{" "}
Expand Down Expand Up @@ -100,7 +116,7 @@ export default function AboutPage() {
{FEATURES.map((f) => {
const c = colorMap[f.color];
return (
<div key={f.title} className="bg-white rounded-xl border border-gray-100 shadow-sm p-6">
<div key={f.title} className="bg-[var(--lp-surface)] border border-[var(--lp-line-soft)] rounded-xl p-6">
<h3 className={`text-base font-semibold mb-2 ${c.text}`}>{f.title}</h3>
<p className="text-sm text-gray-600 leading-relaxed mb-3">{f.description}</p>
<ul className="space-y-1">
Expand All @@ -118,8 +134,8 @@ export default function AboutPage() {
</section>

{/* Who It's For */}
<section className="bg-white rounded-xl shadow-sm border border-gray-100 p-8">
<h2 className="text-2xl font-bold text-gray-900 mb-4">Who Is It For?</h2>
<section className="bg-[var(--lp-surface)] border border-[var(--lp-line-soft)] rounded-xl p-8">
<h2 className="text-xl font-bold text-gray-900 mb-4">Who Is It For?</h2>
<p className="text-gray-700 leading-relaxed mb-5">
Autopilot Monitor is built for anyone responsible for deploying or supporting
Windows devices through Microsoft Intune and Autopilot.
Expand All @@ -142,17 +158,17 @@ export default function AboutPage() {
"Autopilot Monitor is a multi-tenant service with strict per-tenant data isolation — telemetry, configuration, and diagnostics are partitioned and access-scoped to each tenant. MSPs can be granted delegated read access across several customer tenants from a single login.",
},
].map((item) => (
<div key={item.title} className="rounded-lg bg-blue-50 border border-blue-100 p-4">
<h3 className="text-sm font-semibold text-blue-900 mb-2">{item.title}</h3>
<p className="text-sm text-blue-800 leading-relaxed">{item.description}</p>
<div key={item.title} className="rounded-lg bg-[var(--lp-accent-soft)] border border-[var(--lp-accent-line)] p-4">
<h3 className="text-sm font-semibold text-[var(--lp-ink)] mb-2">{item.title}</h3>
<p className="text-sm text-[var(--lp-ink-soft)] leading-relaxed">{item.description}</p>
</div>
))}
</div>
</section>

{/* How It Works */}
<section className="bg-white rounded-xl shadow-sm border border-gray-100 p-8">
<h2 className="text-2xl font-bold text-gray-900 mb-4">How It Works</h2>
<section className="bg-[var(--lp-surface)] border border-[var(--lp-line-soft)] rounded-xl p-8">
<h2 className="text-xl font-bold text-gray-900 mb-4">How It Works</h2>
<p className="text-gray-700 leading-relaxed mb-5">
Autopilot Monitor uses a lightweight .NET agent deployed to devices via an Intune bootstrapper
script. The agent monitors the enrollment process in real time and streams telemetry events
Expand All @@ -169,7 +185,7 @@ export default function AboutPage() {
{ step: "5", text: "On completion, the agent uploads a diagnostics bundle if configured, then removes itself." },
].map((item) => (
<li key={item.step} className="flex items-start gap-3 text-sm text-gray-700">
<span className="inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-blue-600 text-white text-xs font-bold">
<span className="inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-[var(--lp-accent)] text-white text-xs font-bold">
{item.step}
</span>
{item.text}
Expand All @@ -179,8 +195,8 @@ export default function AboutPage() {
</section>

{/* Tech Stack & Platform */}
<section className="bg-white rounded-xl shadow-sm border border-gray-100 p-8">
<h2 className="text-2xl font-bold text-gray-900 mb-4">Technology &amp; Platform</h2>
<section className="bg-[var(--lp-surface)] border border-[var(--lp-line-soft)] rounded-xl p-8">
<h2 className="text-xl font-bold text-gray-900 mb-4">Technology &amp; Platform</h2>
<p className="text-gray-700 leading-relaxed mb-5">
Autopilot Monitor is built on modern, enterprise-grade technology designed to scale with large
device fleets and multi-tenant deployments.
Expand All @@ -190,7 +206,7 @@ export default function AboutPage() {
{
title: "Backend",
items: [
"Azure Functions (.NET 10 Isolated, Flex Consumption) — serverless, scalable API",
"Azure Functions (.NET Isolated, Flex Consumption) — serverless, scalable API",
"Azure Table Storage — high-throughput event ingestion",
"Azure Blob Storage — diagnostics and log bundle storage",
"Azure SignalR Service — real-time push to the portal",
Expand All @@ -199,7 +215,7 @@ export default function AboutPage() {
{
title: "Portal (Web Frontend)",
items: [
"Next.js 15 (React 18) + TypeScript — fast, server-rendered React app",
"Next.js (React) + TypeScript — fast, statically delivered web app",
"Microsoft Entra ID (MSAL) — secure authentication",
"Role-based access control (Admin / Operator / Viewer)",
"Multi-tenant architecture with delegated MSP access",
Expand Down Expand Up @@ -241,8 +257,8 @@ export default function AboutPage() {
</section>

{/* Open Source */}
<section className="bg-white rounded-xl shadow-sm border border-gray-100 p-8">
<h2 className="text-2xl font-bold text-gray-900 mb-4">Open Source &amp; Free to Use</h2>
<section className="bg-[var(--lp-surface)] border border-[var(--lp-line-soft)] rounded-xl p-8">
<h2 className="text-xl font-bold text-gray-900 mb-4">Open Source &amp; Free to Use</h2>
<p className="text-gray-700 leading-relaxed mb-4">
Autopilot Monitor is fully open source and free to use. The complete source code is available on
GitHub under an open license. Contributions, bug reports, and feature requests from the
Expand All @@ -257,58 +273,59 @@ export default function AboutPage() {
</p>
<p className="text-gray-700 leading-relaxed mb-4">
The hosted service is operated by <strong>glueckkanja AG</strong> — see the{" "}
<a href="https://www.glueckkanja.com/en/imprint" target="_blank" rel="noopener noreferrer" className="text-blue-600 hover:text-blue-800 underline">Imprint</a> for company
details and the <Link href="/terms" className="text-blue-600 hover:text-blue-800 underline">Terms of Use</Link>{" "}
<a href="https://www.glueckkanja.com/en/imprint" target="_blank" rel="noopener noreferrer" className="text-[var(--lp-accent-ink)] hover:opacity-80 underline">Imprint</a> for company
details and the <Link href="/terms" className="text-[var(--lp-accent-ink)] hover:opacity-80 underline">Terms of Use</Link>{" "}
for what each plan does and does not commit to.
</p>
<div className="flex flex-wrap gap-3 mt-5">
<a
href="https://github.com/okieselbach/Autopilot-Monitor"
href="https://github.com/okieselbach/AutopilotMonitor"
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center gap-2 rounded-lg border border-gray-200 bg-gray-50 px-4 py-2.5 text-sm font-medium text-gray-700 hover:border-gray-300 hover:bg-gray-100 transition-colors"
className="inline-flex items-center gap-2 rounded-lg border border-[var(--lp-line-soft)] bg-gray-50 px-4 py-2.5 text-sm font-medium text-gray-700 hover:border-gray-300 hover:bg-gray-100 transition-colors"
>
<svg className="w-4 h-4" fill="currentColor" viewBox="0 0 24 24">
<path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z" />
</svg>
View on GitHub
</a>
<a
href="https://github.com/okieselbach/Autopilot-Monitor/issues"
href="https://github.com/okieselbach/AutopilotMonitor/issues"
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center gap-2 rounded-lg border border-gray-200 bg-gray-50 px-4 py-2.5 text-sm font-medium text-gray-700 hover:border-gray-300 hover:bg-gray-100 transition-colors"
className="inline-flex items-center gap-2 rounded-lg border border-[var(--lp-line-soft)] bg-gray-50 px-4 py-2.5 text-sm font-medium text-gray-700 hover:border-gray-300 hover:bg-gray-100 transition-colors"
>
Submit Feedback
</a>
<a
href="https://www.linkedin.com/in/oliver-kieselbach/"
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center gap-2 rounded-lg border border-gray-200 bg-gray-50 px-4 py-2.5 text-sm font-medium text-gray-700 hover:border-gray-300 hover:bg-gray-100 transition-colors"
className="inline-flex items-center gap-2 rounded-lg border border-[var(--lp-line-soft)] bg-gray-50 px-4 py-2.5 text-sm font-medium text-gray-700 hover:border-gray-300 hover:bg-gray-100 transition-colors"
>
Oliver Kieselbach on LinkedIn
</a>
</div>
</section>

{/* Quick Links */}
<section className="bg-white rounded-xl shadow-sm border border-gray-100 p-8">
<h2 className="text-2xl font-bold text-gray-900 mb-4">Explore Further</h2>
<section className="bg-[var(--lp-surface)] border border-[var(--lp-line-soft)] rounded-xl p-8">
<h2 className="text-xl font-bold text-gray-900 mb-4">Explore Further</h2>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3 text-sm">
<a href={DOCS_URL} target="_blank" rel="noopener noreferrer" className="rounded-lg border border-gray-200 px-4 py-3 hover:border-blue-300 hover:bg-blue-50/50 transition-colors text-gray-700 font-medium">
<a href={DOCS_URL} target="_blank" rel="noopener noreferrer" className="rounded-lg border border-[var(--lp-line-soft)] px-4 py-3 hover:border-[var(--lp-accent-line)] hover:bg-[var(--lp-accent-soft)] transition-colors text-gray-700 font-medium">
Documentation →
</a>
<a href={`${DOCS_URL}/changelog/platform-changelog`} target="_blank" rel="noopener noreferrer" className="rounded-lg border border-gray-200 px-4 py-3 hover:border-blue-300 hover:bg-blue-50/50 transition-colors text-gray-700 font-medium">
<a href={`${DOCS_URL}/changelog/platform-changelog`} target="_blank" rel="noopener noreferrer" className="rounded-lg border border-[var(--lp-line-soft)] px-4 py-3 hover:border-[var(--lp-accent-line)] hover:bg-[var(--lp-accent-soft)] transition-colors text-gray-700 font-medium">
Changelog →
</a>
<Link href="/privacy" className="rounded-lg border border-gray-200 px-4 py-3 hover:border-blue-300 hover:bg-blue-50/50 transition-colors text-gray-700 font-medium">
<Link href="/privacy" className="rounded-lg border border-[var(--lp-line-soft)] px-4 py-3 hover:border-[var(--lp-accent-line)] hover:bg-[var(--lp-accent-soft)] transition-colors text-gray-700 font-medium">
Privacy Policy →
</Link>
</div>
</section>

</main>
<SiteFooter />
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ export function RestoreRowDiffModal({
type="button"
onClick={commit}
disabled={committing}
className="px-3 py-1.5 bg-blue-600 hover:bg-blue-700 disabled:opacity-50 text-white text-sm rounded-md transition-colors"
className="px-3 py-1.5 bg-green-600 hover:bg-green-700 disabled:opacity-50 text-white text-sm rounded-md transition-colors"
>
{committing ? "Restoring…" : "Restore row"}
</button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ function RestoreInputRow({
// — only null is rejected. Match that here so an Azure Table row with
// a literal empty key (legal per spec) can be previewed/restored.
disabled={disabled || !tableName}
className="px-3 py-1.5 bg-blue-600 hover:bg-blue-700 disabled:opacity-50 text-white text-sm rounded-md transition-colors"
className="px-3 py-1.5 bg-green-600 hover:bg-green-700 disabled:opacity-50 text-white text-sm rounded-md transition-colors"
>
Preview restore
</button>
Expand Down
2 changes: 1 addition & 1 deletion src/Web/autopilot-monitor-web/app/admin/backups/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ export default function BackupsListPage() {
type="button"
onClick={triggerBackup}
disabled={triggering || activeJob !== null}
className="px-3 py-1.5 bg-blue-600 hover:bg-blue-700 disabled:opacity-50 text-white text-sm rounded-md transition-colors"
className="px-3 py-1.5 bg-green-600 hover:bg-green-700 disabled:opacity-50 text-white text-sm rounded-md transition-colors"
>
{triggering ? "Triggering…" : "Run backup now"}
</button>
Expand Down
Loading