chore: center navbar

This commit is contained in:
Alexander Medvedev 2026-09-20 10:27:37 +02:00
parent 08fb16146c
commit db92a2cd07
6 changed files with 73 additions and 59 deletions

64
package-lock.json generated
View File

@ -19,28 +19,28 @@
"d3-scale": "^4.0.2", "d3-scale": "^4.0.2",
"i18next": "^26.4.2", "i18next": "^26.4.2",
"i18next-browser-languagedetector": "^8.2.1", "i18next-browser-languagedetector": "^8.2.1",
"lucide-react": "^1.45.0", "lucide-react": "^1.47.0",
"or": "^0.2.0", "or": "^0.2.0",
"qrcode.react": "^4.2.0", "qrcode.react": "^4.2.0",
"react": "^19.3.0", "react": "^19.3.0",
"react-dom": "^19.3.0", "react-dom": "^19.3.0",
"react-i18next": "^17.0.13", "react-i18next": "^17.0.14",
"react-is": "^19.3.0", "react-is": "^19.3.0",
"react-markdown": "^10.1.0", "react-markdown": "^10.1.0",
"react-router-dom": "^7.18.3", "react-router-dom": "^7.18.4",
"recharts": "^3.10.1", "recharts": "^3.10.1",
"remark-gfm": "^4.0.1" "remark-gfm": "^4.0.1"
}, },
"devDependencies": { "devDependencies": {
"@eslint/js": "^10.0.1", "@eslint/js": "^10.0.1",
"@types/country-list": "^2.1.4", "@types/country-list": "^2.1.4",
"@types/node": "^26.4.0", "@types/node": "^26.6.2",
"@types/react": "^19.3.0", "@types/react": "^19.3.0",
"@types/react-dom": "^19.3.0", "@types/react-dom": "^19.3.0",
"@vitejs/plugin-react": "^6.1.1", "@vitejs/plugin-react": "^6.1.1",
"eslint": "^10.10.0", "eslint": "^10.11.0",
"eslint-plugin-react-hooks": "^7.1.1", "eslint-plugin-react-hooks": "^7.1.1",
"eslint-plugin-react-refresh": "^0.5.6", "eslint-plugin-react-refresh": "^0.5.7",
"globals": "^17.12.0", "globals": "^17.12.0",
"typescript": "^7.0.2", "typescript": "^7.0.2",
"typescript-eslint": "^8.70.0", "typescript-eslint": "^8.70.0",
@ -1065,13 +1065,13 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "26.4.0", "version": "26.6.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-26.4.0.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-26.6.2.tgz",
"integrity": "sha512-faiGnoIrLH/V8cibOMEAZ8pMw6oXqSukl29ra4mN8GdaB2ZewzeaLj+INpV5N+Z1eKWzY+IzaIZH2EIR6YZRNQ==", "integrity": "sha512-X1P21scMv4zGKLYqjdGjaKa7COa0RKVYYZZN/NfvLQ1JegxFhdhpZG/Lyn8AXx6CDUavKAd11v6BvfpkDByK8g==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"undici-types": "~8.3.0" "undici-types": "~8.9.0"
} }
}, },
"node_modules/@types/react": { "node_modules/@types/react": {
@ -2463,9 +2463,9 @@
} }
}, },
"node_modules/eslint": { "node_modules/eslint": {
"version": "10.10.0", "version": "10.11.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-10.10.0.tgz", "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.11.0.tgz",
"integrity": "sha512-NPXn6r5zl4uET1DAVPaOwzX3rut4c0wcmw3dWJAfOsTM5+TogXo0DDjz8pwm/hL8cyVNpHqeK4JpN0NjnyFFNw==", "integrity": "sha512-P7a6UEEqb9G95MYAtqkmsTbVXIYyzIfl6NGOIJk162PaahFxFyeGcrlXYFSiagECg4sEm8IseJdZBKR3rx6MsQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"workspaces": [ "workspaces": [
@ -2542,9 +2542,9 @@
} }
}, },
"node_modules/eslint-plugin-react-refresh": { "node_modules/eslint-plugin-react-refresh": {
"version": "0.5.6", "version": "0.5.7",
"resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.5.6.tgz", "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.5.7.tgz",
"integrity": "sha512-uZnh24On2bk478AkaDAKcpRiYhS3qFSaSNvpXxV6/Ek/BBDICkWGG7MnBSfjnIlCVBei5vsLlIeQYxbF22+Udg==", "integrity": "sha512-XhJSzLljuYD4UjNuFGJu2v7aD3sqNVK12w5/DCUfrNfHWegZo2+TsavNx8MuxMwEquuFAzNbNfXKU0WoZ+YUIg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peerDependencies": { "peerDependencies": {
@ -3584,9 +3584,9 @@
} }
}, },
"node_modules/lucide-react": { "node_modules/lucide-react": {
"version": "1.45.0", "version": "1.47.0",
"resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.45.0.tgz", "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.47.0.tgz",
"integrity": "sha512-yH1ubCAduho9UR7oJhRXIQXogksRILBiTuZC4/bQIGeB9JOkxMlSuEHyyZpo1Z3S0yWJO2KTSUZbjiNvVxeOUw==", "integrity": "sha512-o8C23aXpNQypRY73W7fW02EyvWJinEMXgKeGjFoKym0zj3Q73hD97A1IQps1g8C14HTGsOpZL0Am+xjfgFZAbg==",
"license": "ISC", "license": "ISC",
"peerDependencies": { "peerDependencies": {
"react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"
@ -4777,9 +4777,9 @@
} }
}, },
"node_modules/react-i18next": { "node_modules/react-i18next": {
"version": "17.0.13", "version": "17.0.14",
"resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-17.0.13.tgz", "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-17.0.14.tgz",
"integrity": "sha512-Cc1PscmblIHA1kljTqDwrcVMI21ydgmUzw0UAeQBe7pAOgfuRLfzXze4EUBQoeDiICzFIXXhHFoZxuetNg5D0Q==", "integrity": "sha512-ZpMBfJL3BiXPuYHj5QMY1GwvKJNhE1vCxOJQ8BoMBdHP5XONTfi/Qss1nuRlnFdIl72PKo2jPmw+fxuLjRFgaQ==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.29.7", "@babel/runtime": "^7.29.7",
@ -4860,9 +4860,9 @@
} }
}, },
"node_modules/react-router": { "node_modules/react-router": {
"version": "7.18.3", "version": "7.18.4",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-7.18.3.tgz", "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.18.4.tgz",
"integrity": "sha512-gyXgtdr5uACJ5b1Q4udzjVV+tb/rlHIMJKuJ0e89R4Kzgz47z/rgP0dIKxktqIEUhDHluGTPJJH/wRha7CyqsA==", "integrity": "sha512-PUPQcMhMGRAslLcvtlPz/kmzBEWPhLdgLFrL7pLNepBL6dX0lWj4WD2cUYVgYCuT3jxvghYFg81cDTj44DhetQ==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"cookie": "^1.0.1", "cookie": "^1.0.1",
@ -4882,12 +4882,12 @@
} }
}, },
"node_modules/react-router-dom": { "node_modules/react-router-dom": {
"version": "7.18.3", "version": "7.18.4",
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.18.3.tgz", "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.18.4.tgz",
"integrity": "sha512-ytVbyBBM7vMfRCam25r0WMhSVSom909A8p+8m0/f1w853dz/xfFu6etAT2SEbVoSnI+ZoPRDqIsQXVT89gp7kg==", "integrity": "sha512-yrfmJHIpDG7taCpqKjT1G5B6q3O2K+RN8/fgNf0lTjCwiPbQ0ei6vXX9ZjQR+7ld8Tr7Z5xmyMnZ8YJrphWQUw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"react-router": "7.18.3" "react-router": "7.18.4"
}, },
"engines": { "engines": {
"node": ">=20.0.0" "node": ">=20.0.0"
@ -5288,9 +5288,9 @@
} }
}, },
"node_modules/undici-types": { "node_modules/undici-types": {
"version": "8.3.0", "version": "8.9.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.9.0.tgz",
"integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==", "integrity": "sha512-KTDyRTYX8sWmKXAikPHHSyc63CRPETMctyjKFupcC6OBLXT3xsN0e9aF7m+mIXutFWpUXuedtowG7iLOzp0kQg==",
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },

View File

@ -25,28 +25,28 @@
"d3-scale": "^4.0.2", "d3-scale": "^4.0.2",
"i18next": "^26.4.2", "i18next": "^26.4.2",
"i18next-browser-languagedetector": "^8.2.1", "i18next-browser-languagedetector": "^8.2.1",
"lucide-react": "^1.45.0", "lucide-react": "^1.47.0",
"or": "^0.2.0", "or": "^0.2.0",
"qrcode.react": "^4.2.0", "qrcode.react": "^4.2.0",
"react": "^19.3.0", "react": "^19.3.0",
"react-dom": "^19.3.0", "react-dom": "^19.3.0",
"react-i18next": "^17.0.13", "react-i18next": "^17.0.14",
"react-is": "^19.3.0", "react-is": "^19.3.0",
"react-markdown": "^10.1.0", "react-markdown": "^10.1.0",
"react-router-dom": "^7.18.3", "react-router-dom": "^7.18.4",
"recharts": "^3.10.1", "recharts": "^3.10.1",
"remark-gfm": "^4.0.1" "remark-gfm": "^4.0.1"
}, },
"devDependencies": { "devDependencies": {
"@eslint/js": "^10.0.1", "@eslint/js": "^10.0.1",
"@types/country-list": "^2.1.4", "@types/country-list": "^2.1.4",
"@types/node": "^26.4.0", "@types/node": "^26.6.2",
"@types/react": "^19.3.0", "@types/react": "^19.3.0",
"@types/react-dom": "^19.3.0", "@types/react-dom": "^19.3.0",
"@vitejs/plugin-react": "^6.1.1", "@vitejs/plugin-react": "^6.1.1",
"eslint": "^10.10.0", "eslint": "^10.11.0",
"eslint-plugin-react-hooks": "^7.1.1", "eslint-plugin-react-hooks": "^7.1.1",
"eslint-plugin-react-refresh": "^0.5.6", "eslint-plugin-react-refresh": "^0.5.7",
"globals": "^17.12.0", "globals": "^17.12.0",
"typescript": "^7.0.2", "typescript": "^7.0.2",
"typescript-eslint": "^8.70.0", "typescript-eslint": "^8.70.0",

View File

@ -192,10 +192,16 @@ h3 {
} }
.nav-search-center { .nav-search-center {
flex: 1; position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
display: flex; display: flex;
justify-content: center; justify-content: center;
margin: 0 1.5rem; width: 100%;
max-width: 440px;
z-index: 100;
pointer-events: auto;
} }
.nav-search-input-wrap { .nav-search-input-wrap {
@ -313,8 +319,8 @@ h3 {
margin: 0 0.5rem; margin: 0 0.5rem;
} }
.nav-search { .nav-search-center {
margin: 0 1rem; max-width: 320px;
} }
} }
@ -361,9 +367,13 @@ h3 {
font-size: 1.1rem; font-size: 1.1rem;
} }
.nav-search { .nav-search-center {
position: static;
transform: none;
left: auto;
top: auto;
margin: 0 0 2rem 0; margin: 0 0 2rem 0;
max-width: none; max-width: 100%;
width: 100%; width: 100%;
} }

View File

@ -183,6 +183,14 @@
background: rgba(249, 115, 22, 0.1); background: rgba(249, 115, 22, 0.1);
} }
.nav-search-recent-footer {
display: flex;
justify-content: flex-end;
padding: 6px 10px 4px;
border-top: 1px solid rgba(255, 255, 255, 0.06);
margin-top: 4px;
}
/* ── Generic Item ── */ /* ── Generic Item ── */
.nav-search-item { .nav-search-item {
display: flex; display: flex;

View File

@ -408,20 +408,6 @@ export const NavSearch: React.FC<NavSearchProps> = ({
{/* ── 1. Recent Searches View (Empty query) ── */} {/* ── 1. Recent Searches View (Empty query) ── */}
{showRecentDropdown && ( {showRecentDropdown && (
<div className="nav-search-section"> <div className="nav-search-section">
<div className="nav-search-section-header">
<span className="nav-search-section-title">
<Clock size={13} />
{t('search.recent_title')}
</span>
<button
type="button"
className="nav-search-clear-recent-btn"
onClick={handleClearAllRecent}
>
{t('search.clear_recent')}
</button>
</div>
<div className="nav-search-recent-list"> <div className="nav-search-recent-list">
{recentSearches.map((term, index) => { {recentSearches.map((term, index) => {
const isSelected = selectedIndex === index; const isSelected = selectedIndex === index;
@ -449,6 +435,15 @@ export const NavSearch: React.FC<NavSearchProps> = ({
); );
})} })}
</div> </div>
<div className="nav-search-recent-footer">
<button
type="button"
className="nav-search-clear-recent-btn"
onClick={handleClearAllRecent}
>
{t('search.clear_recent')}
</button>
</div>
</div> </div>
)} )}

View File

@ -628,9 +628,10 @@ const PluginDetail = () => {
// ── Download / purchase handler ────────────────────────────────────────── // ── Download / purchase handler ──────────────────────────────────────────
const handleDownload = async () => { const handleDownload = async () => {
if (!plugin) return; if (!plugin) return;
if (!user) return navigate('/login', { state: { from: `/plugins/${id}` } });
if (plugin.type === 'paid') { if (plugin.type === 'paid') {
if (!user) return navigate('/login', { state: { from: `/plugins/${id}` } });
// Already owns it — download directly, no checkout // Already owns it — download directly, no checkout
if (ownsPlugin) { if (ownsPlugin) {
if (plugin.is_preorder) { if (plugin.is_preorder) {