diff --git a/backend/.env b/backend/.env new file mode 100644 index 0000000..901386b --- /dev/null +++ b/backend/.env @@ -0,0 +1,4 @@ +MINIO_ACCESS_KEY=TDJvsBmbkpUXpCw5M7LA +MINIO_SECRET_KEY=n9scR7W0MZy6FF0bznV98fSgXpdebIQjqZvEr1Yu +MINIO_ENDPOINT=s3.dvirlabs.com +MINIO_BUCKET=navix-icons \ No newline at end of file diff --git a/backend/__pycache__/main.cpython-312.pyc b/backend/__pycache__/main.cpython-312.pyc new file mode 100644 index 0000000..1d80115 Binary files /dev/null and b/backend/__pycache__/main.cpython-312.pyc differ diff --git a/backend/apps.yaml b/backend/apps.yaml index e29b753..5d815ea 100644 --- a/backend/apps.yaml +++ b/backend/apps.yaml @@ -1,25 +1,25 @@ sections: - apps: - description: Dashboards - icon: http://192.168.10.118:1111/icons/grafana.svg + icon: grafana.svg name: Grafana url: https://grafana.dvirlabs.com - description: Monitoring - icon: http://192.168.10.118:1111/icons/prometheus.svg + icon: prometheus.svg name: Prometheus url: https://prometheus.dvirlabs.com name: Monitoring - apps: - description: Git server - icon: http://192.168.10.118:1111/icons/gitea.svg + icon: gitea.svg name: Gitea url: https://git.dvirlabs.com - description: Container registry - icon: http://192.168.10.118:1111/icons/harbor.svg + icon: harbor.svg name: Harbor url: https://harbor.dvirlabs.com - description: CI/CD - icon: http://192.168.10.118:1111/icons/woodpecker-ci.svg + icon: woodpecker-ci.svg name: Woodpecker url: https://woodpecker.dvirlabs.com name: Dev-tools \ No newline at end of file diff --git a/backend/main.py b/backend/main.py index 2a70f2b..7f6354f 100644 --- a/backend/main.py +++ b/backend/main.py @@ -1,5 +1,8 @@ from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware +from fastapi.responses import JSONResponse +import os +from dotenv import load_dotenv import yaml from pathlib import Path from pydantic import BaseModel @@ -17,12 +20,20 @@ app.add_middleware( allow_headers=["*"], ) +load_dotenv() + +# Load ENV variables +MINIO_ENDPOINT = os.getenv("MINIO_ENDPOINT") +MINIO_ACCESS_KEY = os.getenv("MINIO_ACCESS_KEY") +MINIO_SECRET_KEY = os.getenv("MINIO_SECRET_KEY") +MINIO_BUCKET = os.getenv("MINIO_BUCKET") + # MinIO connection with access and secret keys minio_client = Minio( - "minio.dvirlabs.com", - access_key="YOUR_MINIO_ACCESS_KEY", - secret_key="YOUR_MINIO_SECRET_KEY", - secure=True # Set to False if using HTTP + MINIO_ENDPOINT, + access_key=MINIO_ACCESS_KEY, + secret_key=MINIO_SECRET_KEY, + secure=True ) BUCKET = "navix-icons" @@ -76,16 +87,10 @@ def add_app(entry: AppEntry): return {"status": "added"} @app.get("/icon/{filename}") -def get_presigned_icon_url(filename: str): - try: - url = minio_client.presigned_get_object( - bucket_name=BUCKET, - object_name=filename, - expires=timedelta(hours=1) - ) - return {"url": url} - except Exception as e: - return {"error": str(e)} +def get_public_icon_url(filename: str): + url = f"https://{MINIO_ENDPOINT}/{MINIO_BUCKET}/{filename}" + return JSONResponse(content={"url": url}) + if __name__ == "__main__": diff --git a/frontend/src/components/AppCard.jsx b/frontend/src/components/AppCard.jsx index 4e2fdc6..9fe7f08 100644 --- a/frontend/src/components/AppCard.jsx +++ b/frontend/src/components/AppCard.jsx @@ -1,25 +1,37 @@ import { useEffect, useState } from 'react'; -import { getIconUrl } from '../services/api'; +import '../style/AppCard.css'; +import { getIconUrl } from '../services/api'; function AppCard({ app }) { - const [iconUrl, setIconUrl] = useState(''); + const [iconUrl, setIconUrl] = useState(null); useEffect(() => { - if (app.icon) { - getIconUrl(app.icon) - .then(setIconUrl) - .catch(() => setIconUrl('fallback-icon.svg')); - } - }, [app.icon]); + if (app.icon) { + getIconUrl(app.icon) + .then((url) => { + console.log('Presigned icon URL for', app.name, ':', url); + setIconUrl(url); + }) + .catch((err) => { + console.error(`Failed to load icon for ${app.name}:`, err); + }); + } +}, [app.icon, app.name]); return ( - -
- {app.name} -
-

{app.name}

-

{app.description}

-
+
+ +
+ {iconUrl ? ( + {app.name} + ) : ( + ⚠️ + )} +
+

{app.name}

+

{app.description}

+
+
); } diff --git a/frontend/src/services/api.js b/frontend/src/services/api.js index 31231bb..d9929ed 100644 --- a/frontend/src/services/api.js +++ b/frontend/src/services/api.js @@ -18,5 +18,5 @@ export async function getIconUrl(filename) { const res = await fetch(`/icon/${filename}`); if (!res.ok) throw new Error(`Failed to fetch icon for ${filename}`); const data = await res.json(); - return data.url; -} \ No newline at end of file + return data.url; // ✅ must return the actual URL string +} diff --git a/frontend/vite.config.js b/frontend/vite.config.js index 04886e1..ea8be0a 100644 --- a/frontend/vite.config.js +++ b/frontend/vite.config.js @@ -8,6 +8,7 @@ export default defineConfig({ proxy: { '/apps': 'http://localhost:8000', '/add_app': 'http://localhost:8000', + '/icon': 'http://localhost:8000', } } });