feat(screenshots): replace ai mockups with actual application screenshots and enable package publishing
CI & Build NaxOS Web Dashboard / build (push) Successful in 6m50s

This commit is contained in:
Lukas Holzner
2026-09-04 09:04:40 +02:00
parent d987c4bdad
commit cb7a7e3e43
15 changed files with 54 additions and 10 deletions
+19 -4
View File
@@ -31,11 +31,26 @@ jobs:
- name: Publish Package to Gitea Packages - name: Publish Package to Gitea Packages
run: | run: |
tar -czf naxos-ui-dist.tar.gz -C dist . tar -czf naxos-ui-dist.tar.gz -C dist .
echo "Uploading naxos-ui-dist.tar.gz to Gitea Packages..." echo "Uploading naxos-ui-dist.tar.gz to Gitea Packages registry..."
curl -s --fail-with-body -X PUT \ TOKEN="${{ secrets.PACKAGE_TOKEN }}"
-H "Authorization: token ${{ secrets.GITEA_TOKEN }}" \ if [ -z "$TOKEN" ]; then
TOKEN="${{ secrets.GITEA_TOKEN }}"
fi
RESPONSE=$(curl -s -w "\nHTTP_STATUS:%{http_code}" -X PUT \
-H "Authorization: token ${TOKEN}" \
--upload-file naxos-ui-dist.tar.gz \ --upload-file naxos-ui-dist.tar.gz \
"${{ github.server_url }}/api/packages/naxos/generic/naxos-ui/1.0.0/naxos-ui-dist.tar.gz" || echo "Generic package uploaded or exists" "${{ github.server_url }}/api/packages/naxos/generic/naxos-ui/1.0.0/naxos-ui-dist.tar.gz")
STATUS=$(echo "$RESPONSE" | grep "HTTP_STATUS:" | cut -d: -f2)
BODY=$(echo "$RESPONSE" | grep -v "HTTP_STATUS:")
echo "Package upload HTTP status: $STATUS"
if [ "$STATUS" -eq 201 ] || [ "$STATUS" -eq 200 ] || [ "$STATUS" -eq 204 ]; then
echo "Successfully published naxos-ui-dist.tar.gz to Gitea Packages!"
elif [ "$STATUS" -eq 409 ]; then
echo "Package version 1.0.0 already published in Gitea Packages: $BODY"
else
echo "Failed to publish package to Gitea Packages ($STATUS): $BODY"
exit 1
fi
- name: Upload UI Assets Artifact - name: Upload UI Assets Artifact
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3
+5 -3
View File
@@ -6,11 +6,13 @@ The **NaxOS Web Dashboard** is a modern, responsive, non-technical web interface
## Dashboard Showcase ## Dashboard Showcase
| Overview & Telemetry | OpenZFS Storage & Migration | | Overview & Telemetry | OpenZFS Storage Engine |
| :---: | :---: | | :---: | :---: |
| ![Dashboard Overview](public/screenshots/dashboard-overview.jpg) | ![Storage & Migration](public/screenshots/storage-management.jpg) | | ![Dashboard Overview](public/screenshots/dashboard-overview.png) | ![Storage Management](public/screenshots/storage-management.png) |
| **CNCF Perses Analytics** | **App Store & Runtimes** | | **CNCF Perses Analytics** | **App Store & Runtimes** |
| ![Perses Analytics](public/screenshots/perses-analytics.jpg) | ![App Store](public/screenshots/app-store.jpg) | | ![Perses Analytics](public/screenshots/perses-analytics.png) | ![App Store](public/screenshots/app-store.png) |
| **Setup & Migration Wizard** | **File Shares Management** |
| ![Migration Wizard](public/screenshots/migration-wizard.png) | ![Shares Management](public/screenshots/shares-management.png) |
## Key Features ## Key Features
Binary file not shown.

Before

Width:  |  Height:  |  Size: 494 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 440 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 617 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 554 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

+30 -3
View File
@@ -30,9 +30,36 @@ import type {
} from './types/index.js'; } from './types/index.js';
export const App: React.FC = () => { export const App: React.FC = () => {
const [currentTab, setCurrentTab] = useState('overview'); const getInitialTab = () => {
if (typeof window !== 'undefined') {
const hash = window.location.hash.replace('#', '');
if (hash) return hash;
const params = new URLSearchParams(window.location.search);
const tab = params.get('tab');
if (tab) return tab;
}
return 'overview';
};
const [currentTab, setCurrentTab] = useState(getInitialTab);
const [showRebuildModal, setShowRebuildModal] = useState(false); const [showRebuildModal, setShowRebuildModal] = useState(false);
useEffect(() => {
const onHashChange = () => {
const hash = window.location.hash.replace('#', '');
if (hash) setCurrentTab(hash);
};
window.addEventListener('hashchange', onHashChange);
return () => window.removeEventListener('hashchange', onHashChange);
}, []);
const selectTab = (tab: string) => {
setCurrentTab(tab);
if (typeof window !== 'undefined') {
window.location.hash = tab;
}
};
// Application state // Application state
const [status, setStatus] = useState<SystemStatus | null>(null); const [status, setStatus] = useState<SystemStatus | null>(null);
const [pools, setPools] = useState<ZfsPool[]>([]); const [pools, setPools] = useState<ZfsPool[]>([]);
@@ -161,7 +188,7 @@ export const App: React.FC = () => {
return ( return (
<div className="flex h-screen w-screen overflow-hidden bg-slate-950 text-slate-100 font-sans"> <div className="flex h-screen w-screen overflow-hidden bg-slate-950 text-slate-100 font-sans">
<Sidebar currentTab={currentTab} onSelectTab={setCurrentTab} /> <Sidebar currentTab={currentTab} onSelectTab={selectTab} />
<div className="flex-1 flex flex-col min-w-0 overflow-hidden"> <div className="flex-1 flex flex-col min-w-0 overflow-hidden">
<Topbar <Topbar
@@ -177,7 +204,7 @@ export const App: React.FC = () => {
status={status} status={status}
pools={pools} pools={pools}
apps={installedApps} apps={installedApps}
onNavigate={setCurrentTab} onNavigate={selectTab}
/> />
)} )}