mirror of
https://gitlab.w-hs.de/an14051/backerup-website.git
synced 2026-07-27 17:35:29 +00:00
feat: add CasaOS support to TerminalTyper and update related components
This commit is contained in:
@@ -104,11 +104,89 @@ function buildDaterupComposeLines(links: TerminalLinks): Line[] {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildLines(mode: "docker-run" | "docker-compose" | "daterup" | "daterup-compose" = "docker-run", links: TerminalLinks = {}): Line[] {
|
function buildCasaOsLines(links: TerminalLinks): Line[] {
|
||||||
|
const dockerImage = links.dockerImage ?? LINKS.dockerImage;
|
||||||
|
const uiPort = links.uiPort ?? LINKS.uiPort;
|
||||||
|
return [
|
||||||
|
{ type: "comment", text: "# CasaOS custom app compose — import via App Store → Custom Install" },
|
||||||
|
{ type: "output", text: "name: backerup" },
|
||||||
|
{ type: "output", text: "services:" },
|
||||||
|
{ type: "output", text: " backerup:" },
|
||||||
|
{ type: "output", text: ` image: ${dockerImage}` },
|
||||||
|
{ type: "output", text: " ports:" },
|
||||||
|
{ type: "output", text: ` - target: 80` },
|
||||||
|
{ type: "output", text: ` published: "${uiPort}"` },
|
||||||
|
{ type: "output", text: " protocol: tcp" },
|
||||||
|
{ type: "output", text: " volumes:" },
|
||||||
|
{ type: "output", text: " - /var/run/docker.sock:/var/run/docker.sock" },
|
||||||
|
{ type: "output", text: " - /DATA/AppData/backerup/backups:/backups" },
|
||||||
|
{ type: "output", text: " - /DATA/AppData/backerup/config:/app/config" },
|
||||||
|
{ type: "output", text: " environment:" },
|
||||||
|
{ type: "output", text: " - BACKUP_DIR=/backups" },
|
||||||
|
{ type: "output", text: " - BACKUP_CONFIG_DIR=/app/config" },
|
||||||
|
{ type: "output", text: " - HOST_BACKUP_DIR=/DATA/AppData/backerup/backups" },
|
||||||
|
{ type: "output", text: " restart: unless-stopped" },
|
||||||
|
{ type: "output", text: " network_mode: bridge" },
|
||||||
|
{ type: "output", text: "x-casaos:" },
|
||||||
|
{ type: "output", text: " architectures:" },
|
||||||
|
{ type: "output", text: " - amd64" },
|
||||||
|
{ type: "output", text: " - arm64" },
|
||||||
|
{ type: "output", text: " main: backerup" },
|
||||||
|
{ type: "output", text: " description:" },
|
||||||
|
{ type: "output", text: " en_us: Docker container backup — save and share configs" },
|
||||||
|
{ type: "output", text: " tagline:" },
|
||||||
|
{ type: "output", text: " en_us: Container Backup Manager" },
|
||||||
|
{ type: "output", text: " developer: DoomLabs" },
|
||||||
|
{ type: "output", text: " title:" },
|
||||||
|
{ type: "output", text: " en_us: Backerup" },
|
||||||
|
{ type: "output", text: " index: /" },
|
||||||
|
{ type: "output", text: ` port_map: "${uiPort}"` },
|
||||||
|
{ type: "success", text: "✓ Paste this into CasaOS → App Store → Custom Install" },
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildCasaOsDaterupLines(links: TerminalLinks): Line[] {
|
||||||
|
const daterupDockerImage = links.daterupDockerImage ?? LINKS.daterupDockerImage;
|
||||||
|
return [
|
||||||
|
{ type: "comment", text: "# CasaOS custom app compose — import via App Store → Custom Install" },
|
||||||
|
{ type: "output", text: "name: daterup" },
|
||||||
|
{ type: "output", text: "services:" },
|
||||||
|
{ type: "output", text: " daterup:" },
|
||||||
|
{ type: "output", text: ` image: ${daterupDockerImage}` },
|
||||||
|
{ type: "output", text: " ports:" },
|
||||||
|
{ type: "output", text: " - target: 80" },
|
||||||
|
{ type: "output", text: " published: \"8081\"" },
|
||||||
|
{ type: "output", text: " protocol: tcp" },
|
||||||
|
{ type: "output", text: " volumes:" },
|
||||||
|
{ type: "output", text: " - /var/run/docker.sock:/var/run/docker.sock" },
|
||||||
|
{ type: "output", text: " - /DATA/AppData/daterup/config:/app/config" },
|
||||||
|
{ type: "output", text: " restart: unless-stopped" },
|
||||||
|
{ type: "output", text: " network_mode: bridge" },
|
||||||
|
{ type: "output", text: "x-casaos:" },
|
||||||
|
{ type: "output", text: " architectures:" },
|
||||||
|
{ type: "output", text: " - amd64" },
|
||||||
|
{ type: "output", text: " - arm64" },
|
||||||
|
{ type: "output", text: " main: daterup" },
|
||||||
|
{ type: "output", text: " description:" },
|
||||||
|
{ type: "output", text: " en_us: Docker container update manager — one-click image updates" },
|
||||||
|
{ type: "output", text: " tagline:" },
|
||||||
|
{ type: "output", text: " en_us: Container Update Manager" },
|
||||||
|
{ type: "output", text: " developer: DoomLabs" },
|
||||||
|
{ type: "output", text: " title:" },
|
||||||
|
{ type: "output", text: " en_us: Daterup" },
|
||||||
|
{ type: "output", text: " index: /" },
|
||||||
|
{ type: "output", text: " port_map: \"8081\"" },
|
||||||
|
{ type: "success", text: "✓ Paste this into CasaOS → App Store → Custom Install" },
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildLines(mode: "docker-run" | "docker-compose" | "daterup" | "daterup-compose" | "casaos" | "casaos-daterup" = "docker-run", links: TerminalLinks = {}): Line[] {
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case "docker-compose": return buildDockerComposeLines(links);
|
case "docker-compose": return buildDockerComposeLines(links);
|
||||||
case "daterup": return buildDaterupRunLines(links);
|
case "daterup": return buildDaterupRunLines(links);
|
||||||
case "daterup-compose": return buildDaterupComposeLines(links);
|
case "daterup-compose": return buildDaterupComposeLines(links);
|
||||||
|
case "casaos": return buildCasaOsLines(links);
|
||||||
|
case "casaos-daterup": return buildCasaOsDaterupLines(links);
|
||||||
default: return buildDockerRunLines(links);
|
default: return buildDockerRunLines(links);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -142,16 +220,23 @@ function linePrompt(line: Line): string {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function TerminalTyper({ mode = "docker-run", links = {} }: { mode?: "docker-run" | "docker-compose" | "daterup" | "daterup-compose"; links?: TerminalLinks } = {}) {
|
export default function TerminalTyper({ mode = "docker-run", links = {}, casaosMode }: { mode?: "docker-run" | "docker-compose" | "daterup" | "daterup-compose" | "casaos" | "casaos-daterup"; links?: TerminalLinks; casaosMode?: "casaos" | "casaos-daterup" } = {}) {
|
||||||
const LINES = buildLines(mode, links);
|
const LINES = buildLines(mode, links);
|
||||||
|
const CASAOS_LINES = casaosMode ? buildLines(casaosMode, links) : null;
|
||||||
const [doneLines, setDoneLines] = useState<number[]>([]);
|
const [doneLines, setDoneLines] = useState<number[]>([]);
|
||||||
const [current, setCurrent] = useState<{ idx: number; chars: number } | null>({ idx: 0, chars: 0 });
|
const [current, setCurrent] = useState<{ idx: number; chars: number } | null>({ idx: 0, chars: 0 });
|
||||||
const [copied, setCopied] = useState(false);
|
const [copied, setCopied] = useState(false);
|
||||||
|
const [copiedCasaOs, setCopiedCasaOs] = useState(false);
|
||||||
|
|
||||||
const copyToClipboard = () => {
|
const copyToClipboard = () => {
|
||||||
let textToCopy = "";
|
let textToCopy = "";
|
||||||
|
|
||||||
if (mode === "docker-compose" || mode === "daterup-compose") {
|
if (mode === "casaos" || mode === "casaos-daterup") {
|
||||||
|
// Copy all output lines as a clean YAML file
|
||||||
|
textToCopy = LINES.filter(line => line.type === "output")
|
||||||
|
.map(line => line.text)
|
||||||
|
.join("\n");
|
||||||
|
} else if (mode === "docker-compose" || mode === "daterup-compose") {
|
||||||
// For docker-compose, copy the YAML content only
|
// For docker-compose, copy the YAML content only
|
||||||
const startIdx = LINES.findIndex(line => line.type === "output" && line.text === "services:");
|
const startIdx = LINES.findIndex(line => line.type === "output" && line.text === "services:");
|
||||||
const endIdx = LINES.findIndex((line, i) => i > startIdx && line.type === "output" && line.text === "EOF");
|
const endIdx = LINES.findIndex((line, i) => i > startIdx && line.type === "output" && line.text === "EOF");
|
||||||
@@ -175,6 +260,17 @@ export default function TerminalTyper({ mode = "docker-run", links = {} }: { mod
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const copyCasaOs = () => {
|
||||||
|
if (!CASAOS_LINES) return;
|
||||||
|
const text = CASAOS_LINES.filter(line => line.type === "output")
|
||||||
|
.map(line => line.text)
|
||||||
|
.join("\n");
|
||||||
|
navigator.clipboard.writeText(text).then(() => {
|
||||||
|
setCopiedCasaOs(true);
|
||||||
|
setTimeout(() => setCopiedCasaOs(false), 2000);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!current) return;
|
if (!current) return;
|
||||||
|
|
||||||
@@ -204,15 +300,28 @@ export default function TerminalTyper({ mode = "docker-run", links = {} }: { mod
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
<button
|
<div className="flex items-center gap-2 flex-wrap">
|
||||||
onClick={copyToClipboard}
|
<button
|
||||||
className="flex items-center gap-2 px-3 py-1.5 rounded-lg text-xs font-medium text-slate-300 bg-slate-800/50 hover:bg-slate-700/50 transition-colors border border-slate-700/50"
|
onClick={copyToClipboard}
|
||||||
>
|
className="flex items-center gap-2 px-3 py-1.5 rounded-lg text-xs font-medium text-slate-300 bg-slate-800/50 hover:bg-slate-700/50 transition-colors border border-slate-700/50"
|
||||||
<svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
>
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" />
|
<svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||||
</svg>
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" />
|
||||||
{copied ? "Copied!" : "Copy command"}
|
</svg>
|
||||||
</button>
|
{copied ? "Copied!" : "Copy command"}
|
||||||
|
</button>
|
||||||
|
{CASAOS_LINES && (
|
||||||
|
<button
|
||||||
|
onClick={copyCasaOs}
|
||||||
|
className="flex items-center gap-2 px-3 py-1.5 rounded-lg text-xs font-medium text-amber-300 bg-amber-500/10 hover:bg-amber-500/20 transition-colors border border-amber-500/30"
|
||||||
|
>
|
||||||
|
<svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" />
|
||||||
|
</svg>
|
||||||
|
{copiedCasaOs ? "Copied!" : "Copy for CasaOS"}
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
<div className="font-mono text-xs sm:text-sm leading-[1.85] select-none">
|
<div className="font-mono text-xs sm:text-sm leading-[1.85] select-none">
|
||||||
{doneLines.map((i) => {
|
{doneLines.map((i) => {
|
||||||
const line = LINES[i];
|
const line = LINES[i];
|
||||||
|
|||||||
@@ -513,7 +513,7 @@ export default async function DaterupPage() {
|
|||||||
<span className="ml-3 text-xs font-mono text-slate-500">docker-compose setup</span>
|
<span className="ml-3 text-xs font-mono text-slate-500">docker-compose setup</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="p-6">
|
<div className="p-6">
|
||||||
<TerminalTyper mode="daterup-compose" links={{ daterupDockerImage: links.daterupDockerImage }} />
|
<TerminalTyper mode="daterup-compose" links={{ daterupDockerImage: links.daterupDockerImage }} casaosMode="casaos-daterup" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -510,7 +510,7 @@ export default async function LandingPage() {
|
|||||||
<span className="ml-3 text-xs font-mono text-slate-500">docker-compose setup</span>
|
<span className="ml-3 text-xs font-mono text-slate-500">docker-compose setup</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="p-6">
|
<div className="p-6">
|
||||||
<TerminalTyper mode="docker-compose" links={{ dockerImage: links.dockerImage, uiPort: links.uiPort }} />
|
<TerminalTyper mode="docker-compose" links={{ dockerImage: links.dockerImage, uiPort: links.uiPort }} casaosMode="casaos" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -583,7 +583,7 @@ export default async function LandingPage() {
|
|||||||
</SpotlightCard>
|
</SpotlightCard>
|
||||||
</AnimateIn>
|
</AnimateIn>
|
||||||
|
|
||||||
{/* Daterup card */}}
|
{/* Daterup card */}
|
||||||
<AnimateIn variant="fade-up" delay={100}>
|
<AnimateIn variant="fade-up" delay={100}>
|
||||||
<SpotlightCard className="rounded-2xl border border-violet-500/20 bg-gradient-to-br from-violet-500/10 to-purple-600/10 p-8 h-full card-hover flex flex-col">
|
<SpotlightCard className="rounded-2xl border border-violet-500/20 bg-gradient-to-br from-violet-500/10 to-purple-600/10 p-8 h-full card-hover flex flex-col">
|
||||||
<div className="flex items-start justify-between gap-4">
|
<div className="flex items-start justify-between gap-4">
|
||||||
|
|||||||
Reference in New Issue
Block a user