diff --git a/backend/src/config/server.ts b/backend/src/config/server.ts index 5d4710c..132c78c 100644 --- a/backend/src/config/server.ts +++ b/backend/src/config/server.ts @@ -17,10 +17,10 @@ export async function getSettings(db: Database): Promise { throw new Error('SQL Error: ' + result.error) } - return data + return data as ServerSettingsData } -export async function updateSettings(db: Database, data: ServerSettingsData) { +export async function updateSettings(db: Database, data: Partial) { const result = await upsertServerSettings(db, data) if (result && !result.success) { throw new Error('SQL Error: ' + result.error) diff --git a/frontend/src/components/ResultMessage/index.tsx b/frontend/src/components/ResultMessage/index.tsx new file mode 100644 index 0000000..0e8f620 --- /dev/null +++ b/frontend/src/components/ResultMessage/index.tsx @@ -0,0 +1,22 @@ +import { component$ } from '@builder.io/qwik' + +type Props = { + type: 'success' | 'failure' + message: string +} + +export default component$(({ type, message }: Props) => { + const colorClasses = getColorClasses(type) + return

{message}

+}) + +export function getColorClasses(type: Props['type']): string { + switch (type) { + case 'success': + return 'bg-green-800 border-green-700 text-green-100' + case 'failure': + return 'bg-red-800 border-red-700 text-red-100 text-green-100' + default: + return 'bg-green-800 border-green-700 text-green-100' + } +} diff --git a/frontend/src/components/Settings/SubmitButton.tsx b/frontend/src/components/Settings/SubmitButton.tsx new file mode 100644 index 0000000..84452ce --- /dev/null +++ b/frontend/src/components/Settings/SubmitButton.tsx @@ -0,0 +1,23 @@ +import { component$ } from '@builder.io/qwik' +import Spinner from '../Spinner' + +type Props = { + loading: boolean + text: string +} + +export const SubmitButton = component$(({ text, loading }) => { + return ( + + ) +}) diff --git a/frontend/src/components/Spinner/index.tsx b/frontend/src/components/Spinner/index.tsx new file mode 100644 index 0000000..f716885 --- /dev/null +++ b/frontend/src/components/Spinner/index.tsx @@ -0,0 +1,25 @@ +import { component$ } from '@builder.io/qwik' + +export default component$(() => { + return ( +
+ + Loading... +
+ ) +}) diff --git a/frontend/src/routes/(admin)/settings/(admin)/server-settings/about/index.tsx b/frontend/src/routes/(admin)/settings/(admin)/server-settings/about/index.tsx index 0389cde..2ff423a 100644 --- a/frontend/src/routes/(admin)/settings/(admin)/server-settings/about/index.tsx +++ b/frontend/src/routes/(admin)/settings/(admin)/server-settings/about/index.tsx @@ -4,6 +4,8 @@ import { getDatabase } from 'wildebeest/backend/src/database' import { updateSettings } from 'wildebeest/backend/src/config/server' import { TextArea } from '~/components/Settings/TextArea' import { serverSettingsLoader } from '../layout' +import { SubmitButton } from '~/components/Settings/SubmitButton' +import ResultMessage from '~/components/ResultMessage' const zodSchema = zod$({ 'extended description': z.string().min(1), @@ -31,6 +33,9 @@ export default component$(() => { const existingSettings = serverSettingsLoader() const saveAction = action() + const showSuccessfulResult = !!saveAction.value?.success + const showUnsuccessfulResult = !!saveAction.value && !saveAction.value.success + return (

Provide in-depth information about how the server is operated, moderated, funded.

@@ -56,12 +61,13 @@ export default component$(() => { value={existingSettings.value['privacy policy']} /> - + {showSuccessfulResult && } + + {showUnsuccessfulResult && ( + + )} + + ) }) diff --git a/frontend/src/routes/(admin)/settings/(admin)/server-settings/branding/index.tsx b/frontend/src/routes/(admin)/settings/(admin)/server-settings/branding/index.tsx index c59016b..5ccdf42 100644 --- a/frontend/src/routes/(admin)/settings/(admin)/server-settings/branding/index.tsx +++ b/frontend/src/routes/(admin)/settings/(admin)/server-settings/branding/index.tsx @@ -5,6 +5,8 @@ import { updateSettings } from 'wildebeest/backend/src/config/server' import { TextArea } from '~/components/Settings/TextArea' import { TextInput } from '~/components/Settings/TextInput' import { serverSettingsLoader } from '../layout' +import ResultMessage from '~/components/ResultMessage' +import { SubmitButton } from '~/components/Settings/SubmitButton' const zodSchema = zod$({ 'server name': z.string().min(1), @@ -32,6 +34,9 @@ export default component$(() => { const existingSettings = serverSettingsLoader() const saveAction = action() + const showSuccessfulResult = !!saveAction.value?.success + const showUnsuccessfulResult = !!saveAction.value && !saveAction.value.success + return (

@@ -58,12 +63,13 @@ export default component$(() => { description="A short description to help uniquely identify your server. Who is running it, who is it for?" /> - + {showSuccessfulResult && } + + {showUnsuccessfulResult && ( + + )} + + ) }) diff --git a/frontend/src/routes/(admin)/settings/(admin)/server-settings/layout.tsx b/frontend/src/routes/(admin)/settings/(admin)/server-settings/layout.tsx index cba57a4..962d199 100644 --- a/frontend/src/routes/(admin)/settings/(admin)/server-settings/layout.tsx +++ b/frontend/src/routes/(admin)/settings/(admin)/server-settings/layout.tsx @@ -10,15 +10,9 @@ export type ServerSettingsData = ServerBrandingData & ServerAboutData export const serverSettingsLoader = loader$>>(async ({ platform }) => { const database = await getDatabase(platform) - const settingsResp = await getSettings(database) - let settingsData: Partial = {} - try { - settingsData = await settingsResp.json() - } catch { - settingsData = {} - } + const settings = await getSettings(database) - return JSON.parse(JSON.stringify(settingsData)) + return JSON.parse(JSON.stringify(settings)) }) export default component$(() => { diff --git a/frontend/src/routes/(admin)/settings/(admin)/server-settings/rules/edit/[id]/index.tsx b/frontend/src/routes/(admin)/settings/(admin)/server-settings/rules/edit/[id]/index.tsx index a8a05e5..80068a6 100644 --- a/frontend/src/routes/(admin)/settings/(admin)/server-settings/rules/edit/[id]/index.tsx +++ b/frontend/src/routes/(admin)/settings/(admin)/server-settings/rules/edit/[id]/index.tsx @@ -4,6 +4,7 @@ import { getDatabase } from 'wildebeest/backend/src/database' import { getRules, upsertRule } from 'wildebeest/backend/src/config/rules' import { TextArea } from '~/components/Settings/TextArea' import { getErrorHtml } from '~/utils/getErrorHtml/getErrorHtml' +import { SubmitButton } from '~/components/Settings/SubmitButton' export type ServerSettingsData = { rules: string[] } @@ -34,7 +35,7 @@ export const ruleLoader = loader$>(async ( const database = await getDatabase(platform) const rules = await getRules(database) - const rule: { id: number; text: string } | undefined = rules.find((r) => r.id === +params['id']) + const rule: { id: string; text: string } | undefined = rules.find((r) => r.id === params['id']) if (!rule) { throw html(404, getErrorHtml('The selected rule could not be found')) @@ -76,12 +77,7 @@ export default component$(() => { /> - + ) diff --git a/frontend/src/routes/(admin)/settings/(admin)/server-settings/rules/index.tsx b/frontend/src/routes/(admin)/settings/(admin)/server-settings/rules/index.tsx index 08ec5a4..56d95f6 100644 --- a/frontend/src/routes/(admin)/settings/(admin)/server-settings/rules/index.tsx +++ b/frontend/src/routes/(admin)/settings/(admin)/server-settings/rules/index.tsx @@ -3,6 +3,7 @@ import { action$, Form, Link, loader$, z, zod$ } from '@builder.io/qwik-city' import { getDatabase } from 'wildebeest/backend/src/database' import { getRules, deleteRule, upsertRule } from 'wildebeest/backend/src/config/rules' import { TextArea } from '~/components/Settings/TextArea' +import { SubmitButton } from '~/components/Settings/SubmitButton' export type ServerSettingsData = { rules: string[] } @@ -76,12 +77,7 @@ export default component$(() => { /> - +

{rules.value.map(({ id, text }, idx) => { diff --git a/frontend/src/routes/(admin)/settings/(auth)/aliases/index.tsx b/frontend/src/routes/(admin)/settings/(auth)/aliases/index.tsx index 12f7e90..f2fdfd3 100644 --- a/frontend/src/routes/(admin)/settings/(auth)/aliases/index.tsx +++ b/frontend/src/routes/(admin)/settings/(auth)/aliases/index.tsx @@ -1,7 +1,8 @@ -import { component$, useStore, useSignal, $ } from '@builder.io/qwik' +import { component$, useStore, $ } from '@builder.io/qwik' import { getDatabase } from 'wildebeest/backend/src/database' import { action$, Form, zod$, z } from '@builder.io/qwik-city' import { addAlias } from 'wildebeest/backend/src/accounts/alias' +import ResultMessage from '~/components/ResultMessage' const zodSchema = zod$({ alias: z.string().min(1), @@ -29,7 +30,6 @@ export const action = action$(async (data, { platform, json }) => { export default component$(() => { const state = useStore({ alias: '' }) - const toast = useSignal<'success' | 'failure' | null>(null) const handleInput = $((event: Event) => { state.alias = (event.target as HTMLInputElement).value @@ -42,16 +42,15 @@ export default component$(() => {

Account Aliases

- {toast.value === 'success' && ( -
- Successfully created a new alias. You can now initiate the move from the old account. -
- )} - - {toast.value === 'failure' && ( -
- Failed to create alias. -
+ {!!saveAction.value && ( + )}