fix: ACME certificate issuance improvements, null-safe hardening, guided setup UX, and order list enhancements (Issue #9)

- Fix critical cascading NULL status bug in ACME challenge flow that could cause 404s
- Add defense-in-depth NULL handling across all ACME service methods
- Add new GET /api/letsencrypt/prerequisites endpoint for configuration checks
- Add interactive ACME Setup Guide with step-by-step navigation links
- Add URL-based tab navigation in Settings and SSL Management pages
- Harden retry flow: return clear 409 errors for invalid/cancelled orders
- Allow cancellation of invalid orders (backend + frontend)
- Improve error message extraction with consistent getErrorMsg helper
- Add status filter tabs (Active/Completed/Failed/All) for order list
- Add visual dimming for cancelled/invalid orders
- Add enhanced pagination with size changer and total count
- Add comprehensive diagnostic logging with ACME: prefix
- Update README with ACME architecture docs, quick start guide, and troubleshooting

Resolves #9

Made-with: Cursor
This commit is contained in:
taylanbakircioglu
2026-04-04 15:15:05 +03:00
parent c2766eadbd
commit deb784bb65
8 changed files with 427 additions and 49 deletions
+4 -1
View File
@@ -1,6 +1,7 @@
import React, { useEffect, useState } from 'react';
import { Card, Form, Switch, Button, InputNumber, message, Tabs, Input, Select, Collapse, Space, Alert, Tag, Spin, Tooltip } from 'antd';
import { SafetyCertificateOutlined, ApiOutlined, CheckCircleOutlined, CloseCircleOutlined, InfoCircleOutlined } from '@ant-design/icons';
import { useSearchParams } from 'react-router-dom';
import axios from 'axios';
const { Option } = Select;
@@ -33,6 +34,8 @@ const ACME_PROVIDERS = {
};
const Settings = () => {
const [searchParams] = useSearchParams();
const defaultTab = searchParams.get('tab') || 'general';
const [form] = Form.useForm();
const [acmeForm] = Form.useForm();
const [acmeLoading, setAcmeLoading] = useState(false);
@@ -332,7 +335,7 @@ const Settings = () => {
return (
<div>
<Tabs items={tabItems} />
<Tabs items={tabItems} defaultActiveKey={defaultTab} />
</div>
);
};