From 5e2000ec9a97da468a1b07caaa227135203078c8 Mon Sep 17 00:00:00 2001 From: CactusBlue Date: Thu, 20 Feb 2025 09:58:55 -0800 Subject: [PATCH] Add custom pages/contact channel docs (#438) * add some description about contact channels * add some examples of password reset * update the doc * rename things * split examples * remove custom for now * fix error message --------- Co-authored-by: Konsti Wohlwend Co-authored-by: Zai Shi --- docs/fern/docs.yml | 4 + .../page-examples/forgot-password.mdx | 59 ++++++++++++++ .../page-examples/password-reset.mdx | 79 +++++++++++++++++++ .../src/interface/crud/contact-channels.ts | 10 +-- 4 files changed, 147 insertions(+), 5 deletions(-) create mode 100644 docs/fern/docs/pages/customization/page-examples/forgot-password.mdx create mode 100644 docs/fern/docs/pages/customization/page-examples/password-reset.mdx diff --git a/docs/fern/docs.yml b/docs/fern/docs.yml index 117e7eb99..27f09ea0d 100644 --- a/docs/fern/docs.yml +++ b/docs/fern/docs.yml @@ -102,6 +102,10 @@ navigation: path: ./docs/pages/customization/page-examples/sign-in.mdx - page: Sign Up path: ./docs/pages/customization/page-examples/sign-up.mdx + - page: Forgot Password + path: ./docs/pages/customization/page-examples/forgot-password.mdx + - page: Password Reset + path: ./docs/pages/customization/page-examples/password-reset.mdx - section: Others contents: - page: Supabase Integration diff --git a/docs/fern/docs/pages/customization/page-examples/forgot-password.mdx b/docs/fern/docs/pages/customization/page-examples/forgot-password.mdx new file mode 100644 index 000000000..8531ac257 --- /dev/null +++ b/docs/fern/docs/pages/customization/page-examples/forgot-password.mdx @@ -0,0 +1,59 @@ +--- +slug: customization/page-examples/forgot-password +--- + +## Custom page with `ForgotPassword` component + +```tsx +'use client'; +import { ForgotPassword } from "@stackframe/stack"; + +export default function DefaultPasswordReset() { + return ; +} +``` + + +## Custom forgot password form + +```tsx +'use client'; + +import { useStackApp } from "@stackframe/stack"; +import { useState } from "react"; + +export default function CustomForgotPasswordForm() { + const [email, setEmail] = useState(''); + const [error, setError] = useState(''); + const [message, setMessage] = useState(''); + const app = useStackApp(); + + const onSubmit = async () => { + try { + await app.sendForgotPasswordEmail(email); + setMessage('Password reset email sent! Please check your inbox.'); + } catch (err) { + setError(err.message); + } + }; + + return ( +
{ e.preventDefault(); onSubmit(); }}> + {error &&
{error}
} + {message ? ( +
{message}
+ ) : ( + <> + setEmail(e.target.value)} + /> + + + )} +
+ ); +} +``` diff --git a/docs/fern/docs/pages/customization/page-examples/password-reset.mdx b/docs/fern/docs/pages/customization/page-examples/password-reset.mdx new file mode 100644 index 000000000..8722f2a20 --- /dev/null +++ b/docs/fern/docs/pages/customization/page-examples/password-reset.mdx @@ -0,0 +1,79 @@ +--- +slug: customization/page-examples/password-reset +--- + +## Custom page with `PasswordReset` component + +```tsx +'use client'; +import { PasswordReset } from "@stackframe/stack"; + +export default function DefaultPasswordReset() { + return ; +} +``` + + +## Custom password reset form + +```tsx +'use client'; + +import { useStackApp } from "@stackframe/stack"; +import { useState } from "react"; + +export default function CustomPasswordResetForm({ code }: { code: string }) { + const [password, setPassword] = useState(''); + const [confirmPassword, setConfirmPassword] = useState(''); + const [error, setError] = useState(''); + const [success, setSuccess] = useState(false); + const app = useStackApp(); + + const onSubmit = async () => { + if (password !== confirmPassword) { + setError('Passwords do not match'); + return; + } + + try { + const result = await app.resetPassword({ password, code }); + if (result.status === 'error') { + setError('Failed to reset password'); + return; + } + setSuccess(true); + } catch (err) { + setError(err.message); + } + }; + + if (success) { + return
Password successfully reset!
; + } + + return ( +
{ e.preventDefault(); onSubmit(); }}> + {error &&
{error}
} +
+ + setPassword(e.target.value)} + /> +
+
+ + setConfirmPassword(e.target.value)} + /> +
+ +
+ ); +} +``` diff --git a/packages/stack-shared/src/interface/crud/contact-channels.ts b/packages/stack-shared/src/interface/crud/contact-channels.ts index 47c7cb0fa..420ea8abb 100644 --- a/packages/stack-shared/src/interface/crud/contact-channels.ts +++ b/packages/stack-shared/src/interface/crud/contact-channels.ts @@ -46,27 +46,27 @@ export const contactChannelsCrud = createCrud({ docs: { clientRead: { summary: "Get a contact channel", - description: "", + description: "Retrieves a specific contact channel by the user ID and the contact channel ID.", tags: ["Contact Channels"], }, clientCreate: { summary: "Create a contact channel", - description: "", + description: "Add a new contact channel for a user.", tags: ["Contact Channels"], }, clientUpdate: { summary: "Update a contact channel", - description: "", + description: "Updates an existing contact channel. Only the values provided will be updated.", tags: ["Contact Channels"], }, clientDelete: { summary: "Delete a contact channel", - description: "", + description: "Removes a contact channel for a given user.", tags: ["Contact Channels"], }, clientList: { summary: "List contact channels", - description: "", + description: "Retrieves a list of all contact channels for a user.", tags: ["Contact Channels"], } }