From 5e96ab6955d8a021dcf6c1ed3c52b4d813fb6198 Mon Sep 17 00:00:00 2001 From: john Date: Sun, 15 Jun 2025 20:13:18 +0200 Subject: [PATCH 01/32] use dynamic translations --- src/app/auth/components/AuthNavButtons.tsx | 8 ++-- src/app/auth/pages/LoginPage.tsx | 15 ++++--- src/app/auth/pages/SignupPage.tsx | 48 ++++++---------------- src/app/i18n/en.json | 19 +++++++++ src/app/i18n/translationKeys.ts | 24 +++++++++++ src/app/i18n/useTranslations.ts | 13 ++++++ src/components/NewPostWidget.tsx | 10 +++-- 7 files changed, 88 insertions(+), 49 deletions(-) create mode 100644 src/app/i18n/en.json create mode 100644 src/app/i18n/translationKeys.ts create mode 100644 src/app/i18n/useTranslations.ts diff --git a/src/app/auth/components/AuthNavButtons.tsx b/src/app/auth/components/AuthNavButtons.tsx index 6e58d01..f3161f4 100644 --- a/src/app/auth/components/AuthNavButtons.tsx +++ b/src/app/auth/components/AuthNavButtons.tsx @@ -1,8 +1,10 @@ import { useUser } from '../../user/user.ts' import NavButton from '../../../components/buttons/NavButton.tsx' import { useLocation } from 'react-router-dom' +import { useTranslations } from '../../i18n/useTranslations.ts' export default function AuthNavButtons() { + const { t } = useTranslations() const user = useUser() const { pathname } = useLocation() @@ -15,15 +17,15 @@ export default function AuthNavButtons() { if (loggedIn) { return ( <> - logout + {t('nav.logout')} ) } else { const search = redirectQuery.toString() return ( <> - login - register + {t('nav.login')} + {t('nav.register')} ) } diff --git a/src/app/auth/pages/LoginPage.tsx b/src/app/auth/pages/LoginPage.tsx index 1432f32..215d8da 100644 --- a/src/app/auth/pages/LoginPage.tsx +++ b/src/app/auth/pages/LoginPage.tsx @@ -8,12 +8,15 @@ import { useUser } from '../../user/user.ts' import NavBar from '../../../components/NavBar.tsx' import NavButton from '../../../components/buttons/NavButton.tsx' import LinkButton from '../../../components/buttons/LinkButton.tsx' +import { useTranslations } from '../../i18n/useTranslations.ts' interface LoginPageProps { authService: AuthService } export default function LoginPage({ authService }: LoginPageProps) { + const { t } = useTranslations() + const [isSubmitting, setIsSubmitting] = useState(false) const [username, setUsername] = useState('') const [password, setPassword] = useState('') @@ -62,7 +65,7 @@ export default function LoginPage({ authService }: LoginPageProps) { - home + {t('nav.home')} } > @@ -71,7 +74,7 @@ export default function LoginPage({ authService }: LoginPageProps) {
- register instead? + {t('auth.login.register_instead')} {error} diff --git a/src/app/auth/pages/SignupPage.tsx b/src/app/auth/pages/SignupPage.tsx index ab6b376..ec3adba 100644 --- a/src/app/auth/pages/SignupPage.tsx +++ b/src/app/auth/pages/SignupPage.tsx @@ -3,12 +3,12 @@ import { useEffect, useRef, useState, FormEvent, useCallback, Ref } from 'react' import SingleColumnLayout from '../../../layouts/SingleColumnLayout.tsx' import TextInput from '../../../components/inputs/TextInput.tsx' import Button from '../../../components/buttons/Button.tsx' -import AnchorButton from '../../../components/buttons/AnchorButton.tsx' import { invalid, valid, Validation } from '../../../utils/validation.ts' import { AuthService } from '../authService.ts' import LinkButton from '../../../components/buttons/LinkButton.tsx' import NavBar from '../../../components/NavBar.tsx' import NavButton from '../../../components/buttons/NavButton.tsx' +import { useTranslations } from '../../i18n/useTranslations.ts' const SignupCodeKey = 'signupCode' @@ -17,6 +17,7 @@ interface SignupPageProps { } export default function SignupPage({ authService }: SignupPageProps) { + const { t } = useTranslations() const { code } = useParams() const [signupCode, setSignupCode] = useState(null) const [isSubmitting, setIsSubmitting] = useState(false) @@ -31,8 +32,6 @@ export default function SignupPage({ authService }: SignupPageProps) { const userNameInputRef = useRef(null) const passwordInputRef = useRef(null) - const dialogRef = useRef(null) - const navigate = useNavigate() useEffect(() => { @@ -47,10 +46,6 @@ export default function SignupPage({ authService }: SignupPageProps) { theSignupCode = localStorage.getItem(SignupCodeKey) setSignupCode(theSignupCode) } - - if (!theSignupCode) { - dialogRef.current?.showModal() - } }, [code, signupCode]) useEffect(() => {}, [signupCode]) @@ -94,7 +89,7 @@ export default function SignupPage({ authService }: SignupPageProps) { - home + {t('nav.home')} } > @@ -103,6 +98,7 @@ export default function SignupPage({ authService }: SignupPageProps) { -
+
- login instead? + {t('auth.register.login_instead')} {error}
- - -
-

STOP !!!

-

You need an invitation to sign up

-

- I'm surprised you even found your way here without one and honestly I'd prefer it if you - would leave -

-

- If you do want to create an account, you should know who - to contact -

- - I'm sorry I'll go somewhere else :( - -
-
) } interface FormInputProps { id: string + label: string value: string onInput: (value: string) => void error: string | null @@ -179,11 +155,11 @@ interface FormInputProps { ref: Ref } -function FormInput({ id, value, onInput, error, type = 'text', ref }: FormInputProps) { +function FormInput({ id, label, value, onInput, error, type = 'text', ref }: FormInputProps) { return (
{error}
diff --git a/src/app/i18n/en.json b/src/app/i18n/en.json new file mode 100644 index 0000000..6cc6cb5 --- /dev/null +++ b/src/app/i18n/en.json @@ -0,0 +1,19 @@ +{ + "nav.home": "home", + "nav.login": "login", + "nav.register": "register", + "nav.admin": "admin", + "auth.login.cta": "login", + "auth.login.register_instead": "register instead?", + "auth.register.cta": "signup", + "auth.register.login_instead": "login instead?", + "auth.username.label": "username", + "auth.password.label": "password", + "auth.remember_me.label": "stay logged in", + "misc.loading": "wait...", + "nav.logout": "logout", + "post.add_media.cta": "+ add media", + "post.public.label": "public", + "post.submit.cta": "post", + "post.editor.placeholder": "write something..." +} \ No newline at end of file diff --git a/src/app/i18n/translationKeys.ts b/src/app/i18n/translationKeys.ts new file mode 100644 index 0000000..de1c52a --- /dev/null +++ b/src/app/i18n/translationKeys.ts @@ -0,0 +1,24 @@ +export interface Translations { + 'auth.login.cta': string + 'auth.login.register_instead': string + 'auth.password.label': string + 'auth.register.cta': string + 'auth.register.login_instead': string + 'auth.remember_me.label': string + 'auth.username.label': string + + 'misc.loading': string + + 'nav.admin': string + 'nav.home': string + 'nav.login': string + 'nav.logout': string + 'nav.register': string + + 'post.add_media.cta': string + 'post.editor.placeholder': string + 'post.public.label': string + 'post.submit.cta': string +} + +export type TranslationKey = keyof Translations diff --git a/src/app/i18n/useTranslations.ts b/src/app/i18n/useTranslations.ts new file mode 100644 index 0000000..c403be1 --- /dev/null +++ b/src/app/i18n/useTranslations.ts @@ -0,0 +1,13 @@ +import { TranslationKey, Translations } from './translationKeys.ts' +import en from './en.json' assert { type: 'json' } + +export function useTranslations() { + // TODO somehow handle other languages (reactively) + const texts = en as Translations + + function getText(key: K): Translations[K] { + return texts[key] ?? key + } + + return { t: getText } +} diff --git a/src/components/NewPostWidget.tsx b/src/components/NewPostWidget.tsx index ea3496a..d7b4828 100644 --- a/src/components/NewPostWidget.tsx +++ b/src/components/NewPostWidget.tsx @@ -3,6 +3,7 @@ import FancyTextEditor, { TextInputKeyDownEvent } from './inputs/FancyTextEditor import Button from './buttons/Button.tsx' import { openFileDialog } from '../utils/openFileDialog.ts' import makePica from 'pica' +import { useTranslations } from '../app/i18n/useTranslations.ts' interface NewPostWidgetProps { onSubmit: ( @@ -22,6 +23,7 @@ interface Attachment { } export default function NewPostWidget({ onSubmit, isSubmitting = false }: NewPostWidgetProps) { + const { t } = useTranslations() const [content, setContent] = useState('') const [attachments, setAttachments] = useState([]) const [isPublic, setIsPublic] = useState(false) @@ -72,7 +74,7 @@ export default function NewPostWidget({ onSubmit, isSubmitting = false }: NewPos onInput={onContentInput} onKeyDown={onInputKeyDown} className="mb-3" - placeholder="write something..." + placeholder={t('post.editor.placeholder')} /> {attachments.length > 0 && ( @@ -93,7 +95,7 @@ export default function NewPostWidget({ onSubmit, isSubmitting = false }: NewPos
From bc5c2075f4464559d041cc2832689fc332323842 Mon Sep 17 00:00:00 2001 From: john Date: Mon, 16 Jun 2025 21:28:24 +0200 Subject: [PATCH 02/32] some changes --- src/app/auth/components/AuthNavButtons.tsx | 2 +- src/app/auth/pages/LoginPage.tsx | 2 +- src/app/auth/pages/SignupPage.tsx | 2 +- src/app/i18n/translationKeys.ts | 24 ------------- src/app/i18n/translations.ts | 41 ++++++++++++++++++++++ src/app/i18n/{ => translations}/en.json | 0 src/app/i18n/useTranslations.ts | 13 ------- src/components/NewPostWidget.tsx | 2 +- 8 files changed, 45 insertions(+), 41 deletions(-) delete mode 100644 src/app/i18n/translationKeys.ts create mode 100644 src/app/i18n/translations.ts rename src/app/i18n/{ => translations}/en.json (100%) delete mode 100644 src/app/i18n/useTranslations.ts diff --git a/src/app/auth/components/AuthNavButtons.tsx b/src/app/auth/components/AuthNavButtons.tsx index f3161f4..c646888 100644 --- a/src/app/auth/components/AuthNavButtons.tsx +++ b/src/app/auth/components/AuthNavButtons.tsx @@ -1,7 +1,7 @@ import { useUser } from '../../user/user.ts' import NavButton from '../../../components/buttons/NavButton.tsx' import { useLocation } from 'react-router-dom' -import { useTranslations } from '../../i18n/useTranslations.ts' +import { useTranslations } from '../../i18n/translations.ts' export default function AuthNavButtons() { const { t } = useTranslations() diff --git a/src/app/auth/pages/LoginPage.tsx b/src/app/auth/pages/LoginPage.tsx index 215d8da..3838a88 100644 --- a/src/app/auth/pages/LoginPage.tsx +++ b/src/app/auth/pages/LoginPage.tsx @@ -8,7 +8,7 @@ import { useUser } from '../../user/user.ts' import NavBar from '../../../components/NavBar.tsx' import NavButton from '../../../components/buttons/NavButton.tsx' import LinkButton from '../../../components/buttons/LinkButton.tsx' -import { useTranslations } from '../../i18n/useTranslations.ts' +import { useTranslations } from '../../i18n/translations.ts' interface LoginPageProps { authService: AuthService diff --git a/src/app/auth/pages/SignupPage.tsx b/src/app/auth/pages/SignupPage.tsx index ec3adba..2e3a200 100644 --- a/src/app/auth/pages/SignupPage.tsx +++ b/src/app/auth/pages/SignupPage.tsx @@ -8,7 +8,7 @@ import { AuthService } from '../authService.ts' import LinkButton from '../../../components/buttons/LinkButton.tsx' import NavBar from '../../../components/NavBar.tsx' import NavButton from '../../../components/buttons/NavButton.tsx' -import { useTranslations } from '../../i18n/useTranslations.ts' +import { useTranslations } from '../../i18n/translations.ts' const SignupCodeKey = 'signupCode' diff --git a/src/app/i18n/translationKeys.ts b/src/app/i18n/translationKeys.ts deleted file mode 100644 index de1c52a..0000000 --- a/src/app/i18n/translationKeys.ts +++ /dev/null @@ -1,24 +0,0 @@ -export interface Translations { - 'auth.login.cta': string - 'auth.login.register_instead': string - 'auth.password.label': string - 'auth.register.cta': string - 'auth.register.login_instead': string - 'auth.remember_me.label': string - 'auth.username.label': string - - 'misc.loading': string - - 'nav.admin': string - 'nav.home': string - 'nav.login': string - 'nav.logout': string - 'nav.register': string - - 'post.add_media.cta': string - 'post.editor.placeholder': string - 'post.public.label': string - 'post.submit.cta': string -} - -export type TranslationKey = keyof Translations diff --git a/src/app/i18n/translations.ts b/src/app/i18n/translations.ts new file mode 100644 index 0000000..519fc55 --- /dev/null +++ b/src/app/i18n/translations.ts @@ -0,0 +1,41 @@ +import en from './translations/en.json' assert { type: 'json' } + +interface Translation { + 'auth.login.cta': string + 'auth.login.register_instead': string + 'auth.password.label': string + 'auth.register.cta': string + 'auth.register.login_instead': string + 'auth.remember_me.label': string + 'auth.username.label': string + + 'misc.loading': string + + 'nav.admin': string + 'nav.home': string + 'nav.login': string + 'nav.logout': string + 'nav.register': string + + 'post.add_media.cta': string + 'post.editor.placeholder': string + 'post.public.label': string + 'post.submit.cta': string +} + +export type TranslationKey = keyof Translation + +export interface UseTranslations { + t: (key: K) => Translation[K] +} + +export function useTranslations(): UseTranslations { + // TODO somehow handle other languages (reactively) + const texts = en as Translation + + function getText(key: K): Translation[K] { + return texts[key] ?? key + } + + return { t: getText } +} diff --git a/src/app/i18n/en.json b/src/app/i18n/translations/en.json similarity index 100% rename from src/app/i18n/en.json rename to src/app/i18n/translations/en.json diff --git a/src/app/i18n/useTranslations.ts b/src/app/i18n/useTranslations.ts deleted file mode 100644 index c403be1..0000000 --- a/src/app/i18n/useTranslations.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { TranslationKey, Translations } from './translationKeys.ts' -import en from './en.json' assert { type: 'json' } - -export function useTranslations() { - // TODO somehow handle other languages (reactively) - const texts = en as Translations - - function getText(key: K): Translations[K] { - return texts[key] ?? key - } - - return { t: getText } -} diff --git a/src/components/NewPostWidget.tsx b/src/components/NewPostWidget.tsx index d7b4828..c943577 100644 --- a/src/components/NewPostWidget.tsx +++ b/src/components/NewPostWidget.tsx @@ -3,7 +3,7 @@ import FancyTextEditor, { TextInputKeyDownEvent } from './inputs/FancyTextEditor import Button from './buttons/Button.tsx' import { openFileDialog } from '../utils/openFileDialog.ts' import makePica from 'pica' -import { useTranslations } from '../app/i18n/useTranslations.ts' +import { useTranslations } from '../app/i18n/translations.ts' interface NewPostWidgetProps { onSubmit: ( From 1710d5d91d577470a62134da0e8228b2db6d2296 Mon Sep 17 00:00:00 2001 From: john Date: Tue, 17 Jun 2025 09:44:30 +0200 Subject: [PATCH 03/32] remove email from authcodes --- .../subpages/SignupCodesManagementPage.tsx | 29 ++++--------------- src/app/auth/authService.ts | 11 +++++-- 2 files changed, 14 insertions(+), 26 deletions(-) diff --git a/src/app/admin/pages/subpages/SignupCodesManagementPage.tsx b/src/app/admin/pages/subpages/SignupCodesManagementPage.tsx index 4dfdfcb..0075c73 100644 --- a/src/app/admin/pages/subpages/SignupCodesManagementPage.tsx +++ b/src/app/admin/pages/subpages/SignupCodesManagementPage.tsx @@ -1,5 +1,5 @@ import { AuthService } from '../../../auth/authService.ts' -import { useEffect, useState, useRef, MouseEvent } from 'react' +import { useEffect, useState, useRef, MouseEvent, useCallback } from 'react' import { SignupCode } from '../../../auth/signupCode.ts' import { Temporal } from '@js-temporal/polyfill' import Button from '../../../../components/buttons/Button.tsx' @@ -12,25 +12,24 @@ export default function SignupCodesManagementPage({ authService }: SignupCodesMa const [codes, setCodes] = useState([]) const [code, setCode] = useState('') const [name, setName] = useState('') - const [email, setEmail] = useState('') const [isLoading, setIsLoading] = useState(false) const [error, setError] = useState(null) const dialogRef = useRef(null) const [tooltipPosition, setTooltipPosition] = useState<{ x: number; y: number } | null>(null) const [activeCode, setActiveCode] = useState(null) - const fetchCodes = async () => { + const fetchCodes = useCallback(async () => { try { setCodes(await authService.listSignupCodes()) } catch (err) { console.error('Failed to fetch signup codes:', err) } - } + }, [authService]) useEffect(() => { const timeoutId = setTimeout(fetchCodes) return () => clearTimeout(timeoutId) - }, [authService]) + }, [authService, fetchCodes]) const handleCreateCode = async (e: React.FormEvent) => { e.preventDefault() @@ -38,12 +37,11 @@ export default function SignupCodesManagementPage({ authService }: SignupCodesMa setError(null) try { - await authService.createSignupCode(code, email, name) + await authService.createSignupCode(code, name) setCode('') setName('') - setEmail('') dialogRef.current?.close() - fetchCodes() // Refresh the table + fetchCodes() } catch (err) { setError(err instanceof Error ? err.message : 'Failed to create signup code') } finally { @@ -116,7 +114,6 @@ export default function SignupCodesManagementPage({ authService }: SignupCodesMa Code - Email Redeemed By Expires On @@ -134,7 +131,6 @@ export default function SignupCodesManagementPage({ authService }: SignupCodesMa {code.code} - {code.email} {code.redeemedBy || 'Not redeemed'} {formatDate(code.expiresOn)} @@ -191,19 +187,6 @@ export default function SignupCodesManagementPage({ authService }: SignupCodesMa /> -
- - setEmail(e.target.value)} - className="w-full px-3 py-2 border border-gray-300 rounded-md" - /> -
-
@@ -120,7 +120,7 @@ export default function LoginPage({ authService }: LoginPageProps) { {t('auth.login.register_instead')} - {error} + {error} From 1fc52a16b964229ef85d6ddf8d67c40d6902d92a Mon Sep 17 00:00:00 2001 From: john Date: Tue, 17 Jun 2025 09:57:01 +0200 Subject: [PATCH 07/32] v1.24.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2e81fa1..5542282 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "femto-webapp", "private": true, - "version": "1.23.0", + "version": "1.24.0", "type": "module", "scripts": { "dev": "vite --host 0.0.0.0", From c0d08897c1908c519543413aca0f19c1f9a25398 Mon Sep 17 00:00:00 2001 From: john Date: Tue, 17 Jun 2025 09:58:24 +0200 Subject: [PATCH 08/32] change api url --- scripts/bump-build-push.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/bump-build-push.sh b/scripts/bump-build-push.sh index ae679c6..45d88e4 100755 --- a/scripts/bump-build-push.sh +++ b/scripts/bump-build-push.sh @@ -8,8 +8,7 @@ USERNAME="johnbotris" IMAGE_NAME="femto-webapp" # Add this before the docker build line -export VITE_API_URL="https://femto-api.botris.social" - +export VITE_API_URL="https://api.botris.social" # Step 0: Ensure clean working directory if [[ -n $(git status --porcelain) ]]; then From 58a214444fbc17d38a3cc0f83de851d7417d5708 Mon Sep 17 00:00:00 2001 From: john Date: Tue, 17 Jun 2025 09:59:03 +0200 Subject: [PATCH 09/32] v1.25.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5542282..f826503 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "femto-webapp", "private": true, - "version": "1.24.0", + "version": "1.25.0", "type": "module", "scripts": { "dev": "vite --host 0.0.0.0", From df0a145f3bb4f9d921243fe42eae0e6f10fd2338 Mon Sep 17 00:00:00 2001 From: john Date: Tue, 17 Jun 2025 10:09:19 +0200 Subject: [PATCH 10/32] add deployment to build script --- scripts/bump-build-push.sh | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/scripts/bump-build-push.sh b/scripts/bump-build-push.sh index 45d88e4..42c2d57 100755 --- a/scripts/bump-build-push.sh +++ b/scripts/bump-build-push.sh @@ -2,6 +2,15 @@ set -euo pipefail +# Parse command line arguments +DEPLOY=false +for arg in "$@"; do + case "$arg" in + -d|--deploy) DEPLOY=true ;; + *) echo "Unknown option: $arg"; echo "Usage: $0 [-d|--deploy]"; exit 1 ;; + esac +done + # CONFIGURATION REGISTRY="docker.botris.dev" USERNAME="johnbotris" @@ -54,3 +63,10 @@ git push origin main git push origin "v$NEW_VERSION" echo "🎉 Release v$NEW_VERSION complete." + +# Step 6: Deploy if flag is set +if [ "$DEPLOY" = true ]; then + echo "🚀 Deploying to production..." + ssh john@botris.social 'bash /home/john/docker/femto/update.sh' + echo "✅ Deployment complete." +fi From f21d20e08c44d0450bdd52cf38cbcff6e0d2eac6 Mon Sep 17 00:00:00 2001 From: john Date: Tue, 17 Jun 2025 10:30:54 +0200 Subject: [PATCH 11/32] niceify build script --- package.json | 2 +- scripts/{bump-build-push.sh => publish.sh} | 35 ++++++++++++++++++++-- 2 files changed, 33 insertions(+), 4 deletions(-) rename scripts/{bump-build-push.sh => publish.sh} (58%) diff --git a/package.json b/package.json index f826503..e89b605 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "build": "tsc -b && vite build", "lint": "eslint .", "preview": "vite preview", - "build:deploy": "bash scripts/bump-build-push.sh", + "build:deploy": "bash scripts/publish.sh", "generate:schema": "node scripts/generate-schema.mjs" }, "dependencies": { diff --git a/scripts/bump-build-push.sh b/scripts/publish.sh similarity index 58% rename from scripts/bump-build-push.sh rename to scripts/publish.sh index 42c2d57..fbe77c7 100755 --- a/scripts/bump-build-push.sh +++ b/scripts/publish.sh @@ -2,12 +2,41 @@ set -euo pipefail +# Function to display help text +show_help() { + echo "Usage: $0 [OPTIONS]" + echo + echo "Description:" + echo " This script automates the process of bumping the version, building a Docker image," + echo " pushing it to the registry, and optionally deploying to production." + echo + echo "Options:" + echo " -h, --help Display this help message and exit" + echo " -d, --deploy Deploy to production after building and pushing" + echo " --major Bump the major version (x.0.0)" + echo " --minor Bump the minor version (0.x.0)" + echo " --patch Bump the patch version (0.0.x) [default]" + echo + echo "Examples:" + echo " $0 # Bump patch version, build and push" + echo " $0 --minor # Bump minor version, build and push" + echo " $0 --major -d # Bump major version, build, push and deploy" + echo " $0 --patch --deploy # Bump patch version, build, push and deploy" + echo +} + # Parse command line arguments DEPLOY=false +VERSION_TYPE="patch" # Default to patch version bump + for arg in "$@"; do case "$arg" in + -h|--help) show_help; exit 0 ;; -d|--deploy) DEPLOY=true ;; - *) echo "Unknown option: $arg"; echo "Usage: $0 [-d|--deploy]"; exit 1 ;; + --major) VERSION_TYPE="major" ;; + --minor) VERSION_TYPE="minor" ;; + --patch) VERSION_TYPE="patch" ;; + *) echo "Unknown option: $arg"; echo "Usage: $0 [-h|--help] [-d|--deploy] [--major|--minor|--patch]"; exit 1 ;; esac done @@ -30,8 +59,8 @@ OLD_VERSION=$(node -p "require('./package.json').version") echo "🔍 Current version: $OLD_VERSION" # Step 2: Bump version without Git tag/commit -echo "🚀 Bumping minor version..." -yarn version --minor --no-git-tag-version +echo "🚀 Bumping $VERSION_TYPE version..." +yarn version --$VERSION_TYPE --no-git-tag-version NEW_VERSION=$(node -p "require('./package.json').version") echo "📦 New version: $NEW_VERSION" From f7771c7df36c5cadd4268d70e911ba8d709ca846 Mon Sep 17 00:00:00 2001 From: john Date: Tue, 17 Jun 2025 10:47:46 +0200 Subject: [PATCH 12/32] tweak help text --- scripts/publish.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/publish.sh b/scripts/publish.sh index fbe77c7..68a75e4 100755 --- a/scripts/publish.sh +++ b/scripts/publish.sh @@ -11,8 +11,8 @@ show_help() { echo " pushing it to the registry, and optionally deploying to production." echo echo "Options:" - echo " -h, --help Display this help message and exit" - echo " -d, --deploy Deploy to production after building and pushing" + echo " -h,--help Display this help message and exit" + echo " -d,--deploy Deploy to production after building and pushing" echo " --major Bump the major version (x.0.0)" echo " --minor Bump the minor version (0.x.0)" echo " --patch Bump the patch version (0.0.x) [default]" From 7fab3d0d9f40f44f965c79ac90b1722618b2ff00 Mon Sep 17 00:00:00 2001 From: john Date: Tue, 17 Jun 2025 11:18:23 +0200 Subject: [PATCH 13/32] add source code link --- public/forgejo-logo-primary.svg | 40 +++++++++++++++++++++++++++++++++ src/components/NavBar.tsx | 23 ++++++++++++++++--- 2 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 public/forgejo-logo-primary.svg diff --git a/public/forgejo-logo-primary.svg b/public/forgejo-logo-primary.svg new file mode 100644 index 0000000..7f64c1a --- /dev/null +++ b/public/forgejo-logo-primary.svg @@ -0,0 +1,40 @@ + + + + + Forgejo logo + Caesar Schinas + + + + + + + + + + + + + diff --git a/src/components/NavBar.tsx b/src/components/NavBar.tsx index 02baea5..330c7aa 100644 --- a/src/components/NavBar.tsx +++ b/src/components/NavBar.tsx @@ -8,9 +8,26 @@ export default function NavBar({ children }: PropsWithChildren) { const user = useUser() const isSuperUser = user?.roles.includes(Role.SuperUser) return ( -