From 5769b38f746588e4090bbff556ca61582c82f61b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Br=C3=BCckner?= Date: Thu, 4 Jun 2026 13:42:13 +0200 Subject: [PATCH] feat: env badge in header, inline desc edit, clean up deps - Header now shows Production/Development with color-coded dot via import.meta.env.PROD - LinkDashboard: click-to-edit description inline (blur/Enter to save, Escape to cancel) - LoginPage: fix Azure button label to English - Remove unused motion and autoprefixer dependencies --- package-lock.json | 131 +------------------------------ package.json | 2 - src/components/Header.tsx | 4 +- src/components/LinkDashboard.tsx | 36 ++++++++- src/components/LoginPage.tsx | 2 +- 5 files changed, 39 insertions(+), 136 deletions(-) diff --git a/package-lock.json b/package-lock.json index f382720..0d56831 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,7 +19,6 @@ "express": "^4.21.2", "jsonwebtoken": "^9.0.2", "lucide-react": "^0.546.0", - "motion": "^12.23.24", "react": "^19.0.1", "react-dom": "^19.0.1", "vite": "^6.2.3" @@ -30,7 +29,6 @@ "@types/express": "^4.17.21", "@types/jsonwebtoken": "^9.0.9", "@types/node": "^22.14.0", - "autoprefixer": "^10.4.21", "esbuild": "^0.25.0", "tailwindcss": "^4.1.14", "tsx": "^4.21.0", @@ -1629,43 +1627,6 @@ "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", "license": "MIT" }, - "node_modules/autoprefixer": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.5.0.tgz", - "integrity": "sha512-FMhOoZV4+qR6aTUALKX2rEqGG+oyATvwBt9IIzVR5rMa2HRWPkxf+P+PAJLD1I/H5/II+HuZcBJYEFBpq39ong==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "browserslist": "^4.28.2", - "caniuse-lite": "^1.0.30001787", - "fraction.js": "^5.3.4", - "picocolors": "^1.1.1", - "postcss-value-parser": "^4.2.0" - }, - "bin": { - "autoprefixer": "bin/autoprefixer" - }, - "engines": { - "node": "^10 || ^12 || >=14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -2323,47 +2284,6 @@ "node": ">= 0.6" } }, - "node_modules/fraction.js": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz", - "integrity": "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/rawify" - } - }, - "node_modules/framer-motion": { - "version": "12.40.0", - "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.40.0.tgz", - "integrity": "sha512-uaBd3qC1v3KQqBEjwTUd183K6PbS+j0yR9w9VmEOLWA/tnUcSn8Xa3uck7t4dgpDoUss8xQTcj8W2L07lrnLFg==", - "license": "MIT", - "dependencies": { - "motion-dom": "^12.40.0", - "motion-utils": "^12.39.0", - "tslib": "^2.4.0" - }, - "peerDependencies": { - "@emotion/is-prop-valid": "*", - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@emotion/is-prop-valid": { - "optional": true - }, - "react": { - "optional": true - }, - "react-dom": { - "optional": true - } - } - }, "node_modules/fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", @@ -3077,47 +2997,6 @@ "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", "license": "MIT" }, - "node_modules/motion": { - "version": "12.40.0", - "resolved": "https://registry.npmjs.org/motion/-/motion-12.40.0.tgz", - "integrity": "sha512-yjrHUrBFW6kQvjJwRsoiPSAhC5tRwRqNGJWmiJ4CrGnbKp0V88AdzkhBmDoqIsIPfarOe0Uddd37Xq43/gIocA==", - "license": "MIT", - "dependencies": { - "framer-motion": "^12.40.0", - "tslib": "^2.4.0" - }, - "peerDependencies": { - "@emotion/is-prop-valid": "*", - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@emotion/is-prop-valid": { - "optional": true - }, - "react": { - "optional": true - }, - "react-dom": { - "optional": true - } - } - }, - "node_modules/motion-dom": { - "version": "12.40.0", - "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.40.0.tgz", - "integrity": "sha512-HxU3ZaBwNPVQUBQf1xxgq+7JrPNZvjLVxgbpEZL7RrWJnsxOf0/OM+yrHG9ogLQ31Do/r57Oz2gQWPK+6q62mg==", - "license": "MIT", - "dependencies": { - "motion-utils": "^12.39.0" - } - }, - "node_modules/motion-utils": { - "version": "12.39.0", - "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.39.0.tgz", - "integrity": "sha512-8nadJAJjTtqRkmRF36FoJTrywK9nnFmnPwnSMyxaOCU7GDjN9RTMJIxx9De8ErM+vpPhMccr/6fo5WciyQLnMQ==", - "license": "MIT" - }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -3284,13 +3163,6 @@ "node": "^10 || ^12 || >=14" } }, - "node_modules/postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true, - "license": "MIT" - }, "node_modules/prebuild-install": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", @@ -3813,7 +3685,8 @@ "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD" + "license": "0BSD", + "optional": true }, "node_modules/tsx": { "version": "4.22.4", diff --git a/package.json b/package.json index 2a69c66..856e71d 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,6 @@ "express": "^4.21.2", "jsonwebtoken": "^9.0.2", "lucide-react": "^0.546.0", - "motion": "^12.23.24", "react": "^19.0.1", "react-dom": "^19.0.1", "vite": "^6.2.3" @@ -33,7 +32,6 @@ "@types/express": "^4.17.21", "@types/jsonwebtoken": "^9.0.9", "@types/node": "^22.14.0", - "autoprefixer": "^10.4.21", "esbuild": "^0.25.0", "tailwindcss": "^4.1.14", "tsx": "^4.21.0", diff --git a/src/components/Header.tsx b/src/components/Header.tsx index 19a0d09..b205305 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -63,8 +63,8 @@ export default function Header({ {/* System Indicator */}
- - System: Online (Simulated) + + System: {import.meta.env.PROD ? 'Production' : 'Development'}
{/* Mail Inbox */} diff --git a/src/components/LinkDashboard.tsx b/src/components/LinkDashboard.tsx index d5f939d..9aa6f80 100644 --- a/src/components/LinkDashboard.tsx +++ b/src/components/LinkDashboard.tsx @@ -43,6 +43,8 @@ export default function LinkDashboard({ links, currentUser, onAddLink, onUpdateL const [editingId, setEditingId] = useState(null); const [draft, setDraft] = useState(EMPTY_DRAFT); const [activeCategory, setActiveCategory] = useState('all'); + const [editingDescId, setEditingDescId] = useState(null); + const [descDraft, setDescDraft] = useState(''); const categories = useMemo(() => { const set = new Set(); @@ -97,6 +99,16 @@ export default function LinkDashboard({ links, currentUser, onAddLink, onUpdateL setDraft(EMPTY_DRAFT); }; + const startDescEdit = (link: QuickLink) => { + setEditingDescId(link.id); + setDescDraft(link.description); + }; + + const commitDescEdit = (link: QuickLink) => { + onUpdateLink({ ...link, description: descDraft.trim() }); + setEditingDescId(null); + }; + const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); const title = draft.title.trim(); @@ -239,8 +251,28 @@ export default function LinkDashboard({ links, currentUser, onAddLink, onUpdateL - {link.description && ( -

{link.description}

+ {editingDescId === link.id ? ( +