Settings
Verify your email
{description}
diff --git a/config/tailwind/package.json b/config/tailwind/package.json new file mode 100644 index 0000000000..38f4500628 --- /dev/null +++ b/config/tailwind/package.json @@ -0,0 +1,26 @@ +{ + "name": "@pubpub/tailwind", + "type": "module", + "version": "0.0.0", + "private": true, + "license": "MIT", + "exports": { + "./style.css": "./style.css", + "./postcss-config": "./postcss.config.js" + }, + "scripts": {}, + "publishConfig": { + "access": "public" + }, + "peerDependencies": { + "tailwindcss-animate": "catalog:", + "@tailwindcss/typography": "catalog:", + "@tailwindcss/forms": "catalog:" + }, + "dependencies": { + "@tailwindcss/postcss": "catalog:", + "postcss": "catalog:", + "tailwindcss": "catalog:" + }, + "devDependencies": {} +} diff --git a/config/tailwind/postcss.config.js b/config/tailwind/postcss.config.js new file mode 100644 index 0000000000..b78d5b1610 --- /dev/null +++ b/config/tailwind/postcss.config.js @@ -0,0 +1,5 @@ +export default { + plugins: { + "@tailwindcss/postcss": {}, + }, +} diff --git a/config/tailwind/style.css b/config/tailwind/style.css new file mode 100644 index 0000000000..1cffcfa617 --- /dev/null +++ b/config/tailwind/style.css @@ -0,0 +1,192 @@ +/** biome-ignore-all lint/suspicious/noDuplicateCustomProperties: biome doesn't understand tailwind */ +@import "tailwindcss"; + +@plugin "tailwindcss-animate"; +@plugin "@tailwindcss/typography"; + +@custom-variant dark (&:where(.dark, .dark *)); + +@utility container { + margin-inline: auto; + padding-inline: 2rem; + @media (width >= --theme(--breakpoint-sm)) { + max-width: none; + } + @media (width >= 1400px) { + max-width: 1400px; + } +} + +:root { + --radius: 0.625rem; + --background: oklch(1 0 0); + --foreground: oklch(0.145 0 0); + --card: oklch(1 0 0); + --card-foreground: oklch(0.145 0 0); + --popover: oklch(1 0 0); + --popover-foreground: oklch(0.145 0 0); + --primary: oklch(0.205 0 0); + --primary-foreground: oklch(0.985 0 0); + --secondary: oklch(0.97 0 0); + --secondary-foreground: oklch(0.205 0 0); + --muted: oklch(0.97 0 0); + --muted-foreground: oklch(0.556 0 0); + --accent: oklch(0.97 0 0); + --accent-foreground: oklch(0.205 0 0); + --destructive: oklch(0.577 0.245 27.325); + --border: oklch(0.922 0 0); + --input: oklch(0.922 0 0); + --ring: oklch(0.708 0 0); + --chart-1: oklch(0.646 0.222 41.116); + --chart-2: oklch(0.6 0.118 184.704); + --chart-3: oklch(0.398 0.07 227.392); + --chart-4: oklch(0.828 0.189 84.429); + --chart-5: oklch(0.769 0.188 70.08); + --sidebar: oklch(0.985 0 0); + --sidebar-foreground: oklch(0.145 0 0); + --sidebar-primary: oklch(0.205 0 0); + --sidebar-primary-foreground: oklch(0.985 0 0); + --sidebar-accent: oklch(0.97 0 0); + --sidebar-accent-foreground: oklch(0.205 0 0); + --sidebar-border: oklch(0.922 0 0); + --sidebar-ring: oklch(0.708 0 0); + + @variant dark { + --hwhite: oklch(89.763% 0.00435 15.946); + + --background: oklch(17.304% 0.00002 271.152); + --foreground: var(--hwhite); + --card: oklch(0.205 0 0); + --card-foreground: var(--hwhite); + --popover: oklch(0.205 0 0); + --popover-foreground: var(--hwhite); + --primary: oklch(0.922 0 0); + --primary-foreground: oklch(0.205 0 0); + --secondary: oklch(0.269 0 0); + --secondary-foreground: var(--hwhite); + --muted: oklch(0.269 0 0); + --muted-foreground: oklch(0.708 0 0); + --accent: oklch(0.269 0 0); + --accent-foreground: var(--hwhite); + --destructive: oklch(0.704 0.191 22.216); + --border: oklch(1 0 0 / 10%); + --input: oklch(1 0 0 / 15%); + --ring: oklch(0.556 0 0); + --chart-1: oklch(0.488 0.243 264.376); + --chart-2: oklch(0.696 0.17 162.48); + --chart-3: oklch(0.769 0.188 70.08); + --chart-4: oklch(0.627 0.265 303.9); + --chart-5: oklch(0.645 0.246 16.439); + --sidebar: oklch(0.205 0 0); + --sidebar-foreground: var(--hwhite); + --sidebar-primary: oklch(0.488 0.243 264.376); + --sidebar-primary-foreground: var(--hwhite); + --sidebar-accent: oklch(0.269 0 0); + --sidebar-accent-foreground: var(--hwhite); + --sidebar-border: oklch(1 0 0 / 10%); + --sidebar-ring: oklch(0.556 0 0); + } +} + +*, +::after, +::before, +::backdrop, +::file-selector-button { + border-color: var(--border, currentColor); +} + +@theme inline { + --color-destructive: var(--destructive); + --color-destructive-foreground: var(--destructive-foreground); + --color-background: var(--background); + --color-foreground: var(--foreground); + --color-card: var(--card); + --color-card-foreground: var(--card-foreground); + --color-primary: var(--primary); + --color-primary-foreground: var(--primary-foreground); + --color-popover: var(--popover); + --color-popover-foreground: var(--popover-foreground); + --color-secondary: var(--secondary); + --color-secondary-foreground: var(--secondary-foreground); + --color-muted: var(--muted); + --color-muted-foreground: var(--muted-foreground); + --color-accent: var(--accent); + --color-accent-foreground: var(--accent-foreground); + --color-input: var(--input); + --color-border: var(--border); + --color-ring: var(--ring); + + --color-sidebar: var(--sidebar); + --color-sidebar-foreground: var(--sidebar-foreground); + --color-sidebar-primary: var(--sidebar-primary); + --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); + --color-sidebar-accent: var(--sidebar-accent); + --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); + --color-sidebar-border: var(--sidebar-border); + --color-sidebar-ring: var(--sidebar-ring); + --color-sidebar-active: var(--sidebar-active); + + --animate-accordion-down: accordion-down 0.2s ease-out; + --animate-accordion-up: accordion-up 0.2s ease-out; + --animate-collapsible-down: collapsible-down 0.2s ease-out; + --animate-collapsible-up: collapsible-up 0.2s ease-out; + + @keyframes accordion-down { + from { + height: 0; + } + to { + height: var(--radix-accordion-content-height); + } + } + @keyframes accordion-up { + from { + height: var(--radix-accordion-content-height); + } + to { + height: 0; + } + } + @keyframes collapsible-down { + from { + height: 0; + } + to { + height: var(--radix-collapsible-content-height); + } + } + @keyframes collapsible-up { + from { + height: var(--radix-collapsible-content-height); + } + to { + height: 0; + } + } +} + +.editor .token { + font-size: 0.7rem; + color: #3b90f7; + font-family: monospace; + background-color: rgba(59, 144, 247, 0.2); + padding: 2px 1px; + box-shadow: 0px 0px 0px 1px rgba(59, 144, 247, 0.5); + border-radius: 3px; + margin: 0 1px; +} +.editor .jsonata-token { + font-size: 0.7rem; + color: #e7a316; + font-family: monospace; + background-color: rgba(231, 163, 22, 0.2); + padding: 2px 1px; + box-shadow: 0px 0px 0px 1px rgba(231, 163, 22, 0.5); + border-radius: 3px; + margin: 0 1px; +} + +.editor.markdown { + min-height: 200px; +} diff --git a/core/actions/_lib/ActionField.tsx b/core/actions/_lib/ActionField.tsx index a4ecd1136c..a30a8a7182 100644 --- a/core/actions/_lib/ActionField.tsx +++ b/core/actions/_lib/ActionField.tsx @@ -132,11 +132,10 @@ const JSONataToggleButton = memo( aria-label={`Toggle JSONata mode for ${fieldName}`} data-testid={`toggle-jsonata-${fieldName}`} className={cn( - "font-mono font-semibold text-gray-900 hover:bg-amber-50", + "font-mono font-semibold text-foreground hover:bg-amber-50", "transition-colors duration-200", - inputState.state === "jsonata" && - "border-orange-400 bg-orange-50 text-orange-900" + inputState.state === "jsonata" && "border-amber-400 bg-amber-600 text-amber-200" )} onClick={handleToggle} > @@ -241,7 +240,7 @@ const InnerActionField = memo(
+{JSON.stringify(testResult.interpolated, null, 2)}@@ -406,7 +406,7 @@ export function ActionFieldJsonataTestPanel(props: { htmlFor={props.configKey} aria-label="Error: JSONata test interpolated value" > -+{JSON.stringify(testResult.interpolated, null, 2)}diff --git a/core/actions/_lib/ActionForm.tsx b/core/actions/_lib/ActionForm.tsx index 11bbe24279..5f03dffcf7 100644 --- a/core/actions/_lib/ActionForm.tsx +++ b/core/actions/_lib/ActionForm.tsx @@ -77,8 +77,7 @@ export function ActionForm(props: ActionFormProps) { return result.data } - toast({ - title: "Invalid initial values", + toast.error({ description: `Can't parse values ${JSON.stringify(props.values)}: ${result.error.issues.map((issue) => `${issue.path.join(".")}: ${issue.message}`).join("\n")}. This is likely an issue on our end, please report this.`, variant: "destructive", }) diff --git a/core/actions/_lib/triggers/PubInStageForDurationConfigForm.tsx b/core/actions/_lib/triggers/PubInStageForDurationConfigForm.tsx index 1fd159f0c4..505a626a57 100644 --- a/core/actions/_lib/triggers/PubInStageForDurationConfigForm.tsx +++ b/core/actions/_lib/triggers/PubInStageForDurationConfigForm.tsx @@ -32,7 +32,6 @@ export const PubInStageForDurationConfigForm: AddionalConfigFormp.field.onChange( diff --git a/core/app/(user)/communities/AddCommunityForm.tsx b/core/app/(user)/communities/AddCommunityForm.tsx index 707811c3d5..c96e27e500 100644 --- a/core/app/(user)/communities/AddCommunityForm.tsx +++ b/core/app/(user)/communities/AddCommunityForm.tsx @@ -30,10 +30,7 @@ export const AddCommunityForm = (props: Props) => { const result = await runCreateCommunity({ ...data }) if (didSucceed(result)) { props.setOpen(false) - toast({ - title: "Success", - description: "Community created", - }) + toast.success("Community created") } } const form = useForm >({ diff --git a/core/app/(user)/communities/RemoveCommunityButton.tsx b/core/app/(user)/communities/RemoveCommunityButton.tsx index 06bbb1bd76..e062b41238 100644 --- a/core/app/(user)/communities/RemoveCommunityButton.tsx +++ b/core/app/(user)/communities/RemoveCommunityButton.tsx @@ -49,11 +49,7 @@ export const RemoveCommunityButton = ({ community }: { community: TableCommunity onClick={async () => { const response = await runRemoveCommunity({ community }) if (didSucceed(response)) { - toast({ - title: "Success", - description: "Community successfully removed", - variant: "default", - }) + toast.success("Community successfully removed") } }} > diff --git a/core/app/(user)/reset/page.tsx b/core/app/(user)/reset/page.tsx index 5023a0e24d..11274da15c 100644 --- a/core/app/(user)/reset/page.tsx +++ b/core/app/(user)/reset/page.tsx @@ -12,7 +12,7 @@ export default async function Page() { if (!user) { return ( - +diff --git a/core/app/(user)/settings/ResetPasswordButton.tsx b/core/app/(user)/settings/ResetPasswordButton.tsx index 73227fb497..c9fadd67cf 100644 --- a/core/app/(user)/settings/ResetPasswordButton.tsx +++ b/core/app/(user)/settings/ResetPasswordButton.tsx @@ -19,18 +19,10 @@ export const ResetPasswordButton = ({ user }: { user: UserLoginData }) => { const result = await runResetPassword({ email: user.email }) if (result && "error" in result) { - toast({ - title: "Error", - description: result.error, - variant: "destructive", - }) + toast.error(result.error) } - toast({ - title: "Success", - description: "Password reset email sent! Please check your inbox.", - duration: 5000, - }) + toast.success("Password reset email sent! Please check your inbox.") } return ( diff --git a/core/app/(user)/settings/UserInfoForm.tsx b/core/app/(user)/settings/UserInfoForm.tsx index 81f6113078..622117bdea 100644 --- a/core/app/(user)/settings/UserInfoForm.tsx +++ b/core/app/(user)/settings/UserInfoForm.tsx @@ -47,10 +47,7 @@ export function UserInfoForm({ user }: { user: UserLoginData }) { const onSubmit = async (data: z.inferInvalid
It looks like this link has expired. Please request a new one.
) => { const result = await runUpdateUserInfo({ data }) if (result && "success" in result) { - toast({ - title: "Success", - description: "User information updated", - }) + toast.success("User information updated") } } @@ -139,7 +136,7 @@ export function UserInfoForm({ user }: { user: UserLoginData }) { !form.formState.isValid || !form.formState.isDirty } - className="w-min flex-grow-0" + className="w-min grow-0" > Save {form.formState.isSubmitting && } diff --git a/core/app/(user)/settings/page.tsx b/core/app/(user)/settings/page.tsx index 9b81e9db9f..2cc871d17e 100644 --- a/core/app/(user)/settings/page.tsx +++ b/core/app/(user)/settings/page.tsx @@ -28,7 +28,7 @@ export default async function Page() { ) return ( - + @@ -65,7 +65,7 @@ export default async function Page() { {community.name[0]} -Settings
{community.name}+{community.name}) diff --git a/core/app/(user)/verify/page.tsx b/core/app/(user)/verify/page.tsx index 9afa3fbdaa..fb358effdf 100644 --- a/core/app/(user)/verify/page.tsx +++ b/core/app/(user)/verify/page.tsx @@ -43,7 +43,7 @@ export default async function Page({ searchParams }: { searchParams: Promise+ Verify your email
{description}
diff --git a/core/app/RootToaster.tsx b/core/app/RootToaster.tsx deleted file mode 100644 index 8fe4828ab9..0000000000 --- a/core/app/RootToaster.tsx +++ /dev/null @@ -1,54 +0,0 @@ -"use client" - -import type { ToasterToast } from "ui/use-toast" - -import { useEffect } from "react" -import { CircleCheck } from "lucide-react" -import { parseAsBoolean, useQueryStates } from "nuqs" - -import { Toaster } from "ui/toaster" -import { toast } from "ui/use-toast" - -import { entries, fromEntries, keys } from "~/lib/mapping" - -const PERSISTED_TOAST = { - verified: { - title: "Verified", - description: ( - - Your email is now verified - - ), - variant: "success", - }, -} as const satisfies { [key: string]: Omit } - -const usePersistedToasts = () => { - const toastQueries = fromEntries( - keys(PERSISTED_TOAST).map((key) => [key, parseAsBoolean.withDefault(false)]) - ) - - const [params, setParams] = useQueryStates(toastQueries, { - history: "replace", - scroll: false, - }) - const activeToasts = entries(params) - .filter(([_param, active]) => active) - .map(([param]) => param) - - useEffect(() => { - for (const activeToastKey of activeToasts) { - const toastData = PERSISTED_TOAST[activeToastKey] - toast(toastData) - setParams({ - [activeToastKey]: null, - }) - } - }, [activeToasts]) -} - -export const RootToaster = () => { - usePersistedToasts() - - return -} diff --git a/core/app/api/v0/c/[communitySlug]/site/[...ts-rest]/route.ts b/core/app/api/v0/c/[communitySlug]/site/[...ts-rest]/route.ts index 20e3f8a12f..bb0555ff68 100644 --- a/core/app/api/v0/c/[communitySlug]/site/[...ts-rest]/route.ts +++ b/core/app/api/v0/c/[communitySlug]/site/[...ts-rest]/route.ts @@ -190,6 +190,7 @@ const handler = createNextHandler( } } + console.log(rest) const [pubs, pubCount] = await Promise.all([ getPubsWithRelatedValues( { diff --git a/core/app/c/(public)/[communitySlug]/public/forms/[formSlug]/fill/RequestLink.tsx b/core/app/c/(public)/[communitySlug]/public/forms/[formSlug]/fill/RequestLink.tsx index c21372b485..4419f3dfd9 100644 --- a/core/app/c/(public)/[communitySlug]/public/forms/[formSlug]/fill/RequestLink.tsx +++ b/core/app/c/(public)/[communitySlug]/public/forms/[formSlug]/fill/RequestLink.tsx @@ -31,16 +31,13 @@ export const RequestLink = ({ return } - toast({ - title: "Link sent", - description: "Successfully requested new link", - }) + toast.success("Link sent") }, [token, formSlug, pubId, communityId]) return (