style(panel-access): modifying the form structure design

This commit is contained in:
KodekaTeam committed 2026-07-12 00:03:45 +07:00
1 parent b16d19d68b
commit f15253a874
1 file changed
+103 -84
@@ -3,9 +3,9 @@
import { useEffect, useMemo, useState } from "react";
import {
AlertTriangle,
ChevronDown,
Globe2,
Loader2,
RefreshCw,
ShieldCheck,
} from "lucide-react";
import {
@@ -72,9 +72,6 @@ export default function PanelAccessSettingsPanel({
const selectedCapability = capabilities?.proxies.find(
(proxy) => proxy.type === panelProxy,
);
const panelRoutePreview = panelDomain.trim()
? `${panelDomain.trim()} -> ${panelProxy}`
: "No custom panel domain configured";
const canProvision = Boolean(
panelDomain.trim() &&
selectedCapability?.available &&
@@ -140,18 +137,50 @@ export default function PanelAccessSettingsPanel({
return (
<div
className="card"
style={{ padding: 24, display: "flex", flexDirection: "column", gap: 20 }}
style={{
padding: 0,
overflow: "hidden",
display: "flex",
flexDirection: "column",
}}
>
<div
style={{
display: "flex",
alignItems: "center",
justifyContent: "space-between",
gap: 16,
flexWrap: "wrap",
padding: "18px 22px",
borderBottom: "1px solid var(--border)",
}}
>
<div
style={{
display: "flex",
alignItems: "flex-start",
justifyContent: "space-between",
gap: 12,
flexWrap: "wrap",
gap: 11,
minWidth: 0,
}}
>
<div style={{ minWidth: 0 }}>
{/* <span
style={{
width: 22,
height: 22,
flexShrink: 0,
display: "inline-flex",
alignItems: "center",
justifyContent: "center",
borderRadius: "50%",
background: "var(--accent-blue)",
color: "white",
fontSize: 11,
fontWeight: 800,
}}
>
1
</span> */}
<div>
<h2
style={{
display: "flex",
@@ -163,7 +192,7 @@ export default function PanelAccessSettingsPanel({
}}
>
<Globe2 size={16} color="var(--accent-green)" />
Panel Access
Configure Panel Domain
</h2>
<div
style={{
@@ -173,7 +202,9 @@ export default function PanelAccessSettingsPanel({
lineHeight: 1.5,
}}
>
Custom domain provisioning for the Doktainer panel
Set your panel domain and reverse proxy. Doktainer will handle the
rest.
</div>
</div>
</div>
<span className="ui-badge badge-info">
@@ -183,6 +214,14 @@ export default function PanelAccessSettingsPanel({
</span>
</div>
<div
style={{
padding: 22,
display: "flex",
flexDirection: "column",
gap: 18,
}}
>
{error ? (
<div
style={{
@@ -238,8 +277,9 @@ export default function PanelAccessSettingsPanel({
<div
style={{
display: "grid",
gridTemplateColumns: "repeat(auto-fit, minmax(240px, 1fr))",
gap: 16,
gridTemplateColumns: "repeat(auto-fit, minmax(280px, 1fr))",
gap: 14,
alignItems: "start",
}}
>
<div>
@@ -250,65 +290,58 @@ export default function PanelAccessSettingsPanel({
value={panelDomain}
onChange={(event) => setPanelDomain(event.target.value)}
/>
</div>
</div>
<div
style={{
display: "grid",
gridTemplateColumns: "repeat(auto-fit, minmax(240px, 1fr))",
gap: 16,
alignItems: "stretch",
}}
style={{ marginTop: 6, fontSize: 11, color: "var(--text-muted)" }}
>
Enter the domain used to open the Doktainer panel.
</div>
</div>
<div>
<FieldLabel>Reverse Proxy</FieldLabel>
<div
className="ui-pill-switch"
style={{
border: "1px solid var(--border)",
background: "var(--bg-input)",
}}
<FieldLabel>
Reverse Proxy{" "}
<span style={{ fontWeight: 500, color: "var(--text-muted)" }}>
(Auto Detect)
</span>
</FieldLabel>
<div style={{ position: "relative" }}>
<select
className="input"
value={panelProxy}
disabled={loadingCapabilities}
onChange={(event) =>
setPanelProxy(event.target.value as PanelAccessProxy)
}
style={{ width: "100%", appearance: "none", paddingRight: 34 }}
>
{proxyOptions.map((option) => {
const active = panelProxy === option.value;
const capability = capabilities?.proxies.find(
(proxy) => proxy.type === option.value,
);
const disabled =
loadingCapabilities ||
!capability?.available ||
!capability.supportsProvisioning;
const available =
capability?.available && capability.supportsProvisioning;
return (
<button
<option
key={option.value}
type="button"
onClick={() => {
if (!disabled) setPanelProxy(option.value);
}}
disabled={disabled}
title={capability?.reason ?? undefined}
style={{
minHeight: 34,
flex: "1 1 120px",
border: "none",
borderRadius: 6,
background: active ? "#1d4ed8" : "transparent",
color: disabled
? "var(--text-muted)"
: active
? "white"
: "var(--text-secondary)",
fontSize: 12,
fontWeight: 700,
cursor: disabled ? "not-allowed" : "pointer",
opacity: disabled ? 0.55 : 1,
}}
value={option.value}
disabled={!available}
>
{option.label}
</button>
{available ? " (Detected)" : " (Unavailable)"}
</option>
);
})}
</select>
<ChevronDown
size={15}
style={{
position: "absolute",
right: 11,
top: "50%",
transform: "translateY(-50%)",
pointerEvents: "none",
color: "var(--text-muted)",
}}
/>
</div>
{selectedCapability?.reason ? (
<div
@@ -323,14 +356,16 @@ export default function PanelAccessSettingsPanel({
</div>
) : null}
</div>
</div>
<div
style={{
minHeight: 62,
minHeight: 74,
display: "flex",
alignItems: "center",
justifyContent: "space-between",
gap: 12,
padding: "11px 12px",
gap: 16,
padding: "13px 14px",
border: "1px solid var(--border)",
borderRadius: 8,
background: "var(--bg-input)",
@@ -348,7 +383,7 @@ export default function PanelAccessSettingsPanel({
}}
>
<ShieldCheck size={14} color="var(--accent-green)" />
Auto SSL
HTTPS / SSL
</div>
<div
style={{
@@ -357,7 +392,7 @@ export default function PanelAccessSettingsPanel({
color: "var(--text-muted)",
}}
>
Certbot or proxy-managed TLS
Automatically provision SSL certificate
</div>
</div>
<Toggle
@@ -365,7 +400,6 @@ export default function PanelAccessSettingsPanel({
onChange={() => setPanelAutoSsl((current) => !current)}
/>
</div>
</div>
{capabilities?.autoSsl.reason ? (
<div
style={{
@@ -382,36 +416,20 @@ export default function PanelAccessSettingsPanel({
<div
style={{
display: "flex",
justifyContent: "space-between",
justifyContent: "flex-end",
alignItems: "center",
gap: 12,
flexWrap: "wrap",
padding: "12px 14px",
border: "1px solid rgba(59,130,246,0.24)",
borderRadius: 8,
background: "rgba(59,130,246,0.07)",
paddingTop: 2,
}}
>
<div
style={{
display: "flex",
alignItems: "center",
gap: 8,
minWidth: 0,
color: "var(--text-secondary)",
fontSize: 12,
}}
>
<RefreshCw size={14} color="var(--accent-blue)" />
<span>{panelRoutePreview}</span>
</div>
<button
type="button"
className="btn btn-primary"
disabled={!canProvision}
onClick={() => void provisionPanelDomain()}
style={{
minWidth: 168,
minWidth: 164,
opacity: canProvision ? 1 : 0.55,
cursor: canProvision ? "pointer" : "not-allowed",
}}
@@ -422,10 +440,11 @@ export default function PanelAccessSettingsPanel({
Provisioning
</>
) : (
"Provision Panel Domain"
"Configure Domain"
)}
</button>
</div>
</div>
</div>
);
}