fix(ui): clean up settings, automate page, fullscreen logo, and README

- README: simplify to match Stirling-PDF style, add dashboard screenshot
- Settings: remove unsupported languages from dropdown, remove unused
  experimental tools toggle
- Automate: remove hardcoded template pipelines from sidebar
- Fullscreen: add GemLogo icon to header
This commit is contained in:
Siddharth Kumar Sah
2026-03-27 13:50:04 +08:00
parent e6dc7b0a18
commit e3a8558134
5 changed files with 36 additions and 240 deletions
@@ -397,12 +397,7 @@ function SystemSection() {
onChange={(e) => updateSetting("defaultLocale", e.target.value)}
className="px-3 py-1.5 rounded-lg border border-border bg-background text-sm text-foreground"
>
<option value="en">English (en)</option>
<option value="es">Spanish (es)</option>
<option value="fr">French (fr)</option>
<option value="de">German (de)</option>
<option value="zh">Chinese (zh)</option>
<option value="ja">Japanese (ja)</option>
<option value="en">English</option>
</select>
</SettingRow>
@@ -420,32 +415,6 @@ function SystemSection() {
/>
</SettingRow>
<SettingRow
label="Enable Experimental Tools"
description="Show tools that are still in development. These may be unstable."
>
<button
type="button"
onClick={() =>
updateSetting(
"enableExperimentalTools",
settings.enableExperimentalTools === "true" ? "false" : "true",
)
}
className={cn(
"w-11 h-6 rounded-full transition-colors relative",
settings.enableExperimentalTools === "true" ? "bg-primary" : "bg-muted-foreground/30",
)}
>
<span
className={cn(
"block w-4 h-4 rounded-full bg-white absolute top-1 transition-transform",
settings.enableExperimentalTools === "true" ? "translate-x-6" : "translate-x-1",
)}
/>
</button>
</SettingRow>
<div className="pt-4 border-t border-border">
<h4 className="text-sm font-semibold text-foreground mb-3">File Management</h4>
</div>
+6 -110
View File
@@ -1,74 +1,7 @@
import { Globe, Play, ShieldOff, Stamp, Trash2, User, Workflow, Zap } from "lucide-react";
import { Play, Trash2, Workflow } from "lucide-react";
import { useCallback, useEffect, useState } from "react";
import { AppLayout } from "@/components/layout/app-layout";
import { PipelineBuilder, type PipelineStep } from "@/components/tools/pipeline-builder";
import { cn } from "@/lib/utils";
/** Pipeline template definition. */
interface PipelineTemplate {
name: string;
description: string;
icon: React.ComponentType<{ className?: string }>;
color: string;
steps: Array<{ toolId: string; settings: Record<string, unknown> }>;
}
const TEMPLATES: PipelineTemplate[] = [
{
name: "Social Media Ready",
description: "Resize 1080x1080, compress 200KB, strip metadata, convert to WebP",
icon: Globe,
color: "bg-blue-500/10 text-blue-500",
steps: [
{ toolId: "resize", settings: { width: 1080, height: 1080, fit: "cover" } },
{ toolId: "compress", settings: { quality: 80 } },
{ toolId: "strip-metadata", settings: {} },
{ toolId: "convert", settings: { format: "webp" } },
],
},
{
name: "Privacy Clean",
description: "Strip all metadata and convert to JPG",
icon: ShieldOff,
color: "bg-green-500/10 text-green-500",
steps: [
{ toolId: "strip-metadata", settings: {} },
{ toolId: "convert", settings: { format: "jpg" } },
],
},
{
name: "Web Optimization",
description: "Resize to 1920px, convert to WebP, compress to 80% quality",
icon: Zap,
color: "bg-yellow-500/10 text-yellow-500",
steps: [
{ toolId: "resize", settings: { width: 1920, fit: "inside" } },
{ toolId: "convert", settings: { format: "webp" } },
{ toolId: "compress", settings: { quality: 80 } },
],
},
{
name: "Profile Picture",
description: "Resize to 400x400 and compress",
icon: User,
color: "bg-purple-500/10 text-purple-500",
steps: [
{ toolId: "resize", settings: { width: 400, height: 400, fit: "cover" } },
{ toolId: "compress", settings: { quality: 85 } },
],
},
{
name: "Watermark Batch",
description: "Add text watermark, strip metadata, and compress",
icon: Stamp,
color: "bg-red-500/10 text-red-500",
steps: [
{ toolId: "watermark-text", settings: { text: "SAMPLE", opacity: 0.3 } },
{ toolId: "strip-metadata", settings: {} },
{ toolId: "compress", settings: { quality: 85 } },
],
},
];
interface SavedPipeline {
id: string;
@@ -200,17 +133,6 @@ export function AutomatePage() {
[steps],
);
// Load template into builder
const loadTemplate = useCallback((template: PipelineTemplate) => {
const newSteps: PipelineStep[] = template.steps.map((s) => ({
id: crypto.randomUUID(),
toolId: s.toolId,
settings: { ...s.settings },
}));
setSteps(newSteps);
setExecutionResult(null);
}, []);
// Load saved pipeline into builder
const loadSaved = useCallback((pipeline: SavedPipeline) => {
const newSteps: PipelineStep[] = pipeline.steps.map((s) => ({
@@ -225,35 +147,9 @@ export function AutomatePage() {
return (
<AppLayout showToolPanel={false}>
<div className="flex h-full w-full overflow-hidden">
{/* Left sidebar: templates + saved */}
<div className="w-72 border-r border-border overflow-y-auto p-4 space-y-6 shrink-0 hidden md:block">
{/* Templates */}
<div>
<h3 className="text-xs font-semibold uppercase text-muted-foreground tracking-wider mb-3">
Templates
</h3>
<div className="space-y-2">
{TEMPLATES.map((tpl) => (
<button
key={tpl.name}
type="button"
onClick={() => loadTemplate(tpl)}
className="w-full text-left p-3 rounded-lg border border-border hover:bg-muted/50 transition-colors"
>
<div className="flex items-center gap-2 mb-1">
<div className={cn("p-1.5 rounded-md", tpl.color)}>
<tpl.icon className="h-3.5 w-3.5" />
</div>
<span className="text-sm font-medium text-foreground">{tpl.name}</span>
</div>
<p className="text-xs text-muted-foreground line-clamp-2">{tpl.description}</p>
</button>
))}
</div>
</div>
{/* Saved automations */}
{savedPipelines.length > 0 && (
{/* Left sidebar: saved automations */}
{savedPipelines.length > 0 && (
<div className="w-72 border-r border-border overflow-y-auto p-4 space-y-6 shrink-0 hidden md:block">
<div>
<h3 className="text-xs font-semibold uppercase text-muted-foreground tracking-wider mb-3">
Saved Automations
@@ -293,8 +189,8 @@ export function AutomatePage() {
))}
</div>
</div>
)}
</div>
</div>
)}
{/* Main builder area */}
<div className="flex-1 overflow-y-auto p-6">
+6 -1
View File
@@ -4,6 +4,7 @@ import * as icons from "lucide-react";
import { Eye, EyeOff, FileImage, LayoutGrid, List, Search } from "lucide-react";
import { useEffect, useMemo, useState } from "react";
import { Link, useNavigate } from "react-router-dom";
import { GemLogo } from "@/components/common/gem-logo";
import { apiGet } from "@/lib/api";
import { cn } from "@/lib/utils";
@@ -63,7 +64,11 @@ export function FullscreenGridPage() {
{/* Top bar */}
<header className="sticky top-0 z-30 bg-background/95 backdrop-blur-sm border-b border-border">
<div className="max-w-7xl mx-auto px-4 sm:px-6 py-3 flex items-center gap-4">
<Link to="/" className="text-lg font-bold text-foreground shrink-0">
<Link
to="/"
className="flex items-center gap-2 text-lg font-bold text-foreground shrink-0"
>
<GemLogo className="h-6 w-6 text-primary" />
Stirling <span className="text-primary">Image</span>
</Link>