diff --git a/content/docs/guides/oidc.mdx b/content/docs/guides/oidc.mdx index fe9c204..0f0614b 100644 --- a/content/docs/guides/oidc.mdx +++ b/content/docs/guides/oidc.mdx @@ -23,7 +23,9 @@ To set up OIDC authentication with Pocket Id, follow these steps: Go to your Pocket ID dashboard and create a new application. Give it a name and leave the redirect URI blank for now. -TODO: Pocket Id application creation image here +![Pocket ID Application Creation](/assets/docs/pocketid-orca-registration.png?url) + +You can find the OrcaCD logo [here](https://github.com/OrcaCD/orca-cd/tree/main/frontend/public/assets). ### 2. Configure OrcaCD @@ -35,7 +37,7 @@ TODO: Pocket Id application creation image here - **Client Secret**: The client secret from your Pocket Id application. 3. Save the configuration and ensure it is enabled. -TODO: Orca CD OIDC configuration image here +![OrcaCD OIDC Configuration](/assets/docs/orca-sso-registration.png?url) ### 3. Test the Configuration @@ -44,4 +46,4 @@ TODO: Orca CD OIDC configuration image here 3. You will be redirected to the Pocket Id login page. Enter your credentials and log in. 4. After successful authentication, you will be redirected back to OrcaCD and logged in with your Pocket Id account. -TODO: Login page image here +
![OrcaCD Login Page](/assets/docs/sso-login-screen.png?url)
diff --git a/content/docs/guides/reverse-proxy.mdx b/content/docs/guides/reverse-proxy.mdx index 6be3249..1eb304e 100644 --- a/content/docs/guides/reverse-proxy.mdx +++ b/content/docs/guides/reverse-proxy.mdx @@ -11,7 +11,7 @@ TODO To use Traefik as a reverse proxy for OrcaCD, you can add the following labels to your Docker Compose configuration for the OrcaCD Hub service: -```yml +```yml lineNumbers services: hub: image: ghcr.io/orcacd/hub:latest diff --git a/content/docs/helping-out/documentation.mdx b/content/docs/helping-out/documentation.mdx index 4462e3f..e9ad91a 100644 --- a/content/docs/helping-out/documentation.mdx +++ b/content/docs/helping-out/documentation.mdx @@ -17,7 +17,7 @@ All markdown pages are under `/content/docs`. The file `meta.json` controls the 3. Add frontmatter: -```yaml +```yaml lineNumbers --- title: Installation description: Get OrcaCD running quickly with Docker installation diff --git a/content/docs/troubleshooting/account-recovery.mdx b/content/docs/troubleshooting/account-recovery.mdx new file mode 100644 index 0000000..95070f2 --- /dev/null +++ b/content/docs/troubleshooting/account-recovery.mdx @@ -0,0 +1,17 @@ +--- +title: Account Recovery +description: Steps to recover your account if you have lost access +--- + +There are two ways to reset a password for a user: + +1. UI: An admin can reset the password for a user in the admin panel under the "Users" tab by clicking on the three dots next to the user's name and selecting "Edit". +2. Terminal: You can reset a password for a user by running `hub reset-password `. To execute this script with Docker you have to run the following command: + +```bash +docker compose exec hub /app/hub reset-password +``` + +The user with the reset password has to change the password on the next login. + + diff --git a/public/assets/docs/orca-sso-registration.png b/public/assets/docs/orca-sso-registration.png new file mode 100644 index 0000000..9087c39 Binary files /dev/null and b/public/assets/docs/orca-sso-registration.png differ diff --git a/public/assets/docs/pocketid-orca-registration.png b/public/assets/docs/pocketid-orca-registration.png new file mode 100644 index 0000000..529abc9 Binary files /dev/null and b/public/assets/docs/pocketid-orca-registration.png differ diff --git a/public/assets/docs/sso-login-screen.png b/public/assets/docs/sso-login-screen.png new file mode 100644 index 0000000..4aba7c4 Binary files /dev/null and b/public/assets/docs/sso-login-screen.png differ diff --git a/src/components/account-recovery-terminal.tsx b/src/components/account-recovery-terminal.tsx new file mode 100644 index 0000000..698bc0e --- /dev/null +++ b/src/components/account-recovery-terminal.tsx @@ -0,0 +1,26 @@ +import { AnimatedSpan, Terminal, TypingAnimation } from "./terminal"; + +export function AccountRecoveryTerminal() { + return ( + + + $ docker compose exec hub /app/hub reset-password 019dc111-5220-77bc-9729-2335f88fa658 + + + {` +╭────────────────────────────────────────────────────────────────────╮ +│ │ +│ Password Reset Successful │ +│ │ +│ User ID: 019dc111-5220-77bc-9729-2335f88fa658 │ +│ Email: test@orcacd.dev │ +│ New temporary password: w&BU6G,WM#!MX9M4eq │ +│ │ +│ Important: The user must change this password on the next login. │ +│ │ +╰────────────────────────────────────────────────────────────────────╯ +`} + + + ); +} diff --git a/src/components/terminal.tsx b/src/components/terminal.tsx new file mode 100644 index 0000000..29e8477 --- /dev/null +++ b/src/components/terminal.tsx @@ -0,0 +1,111 @@ +"use client"; + +import { cn } from "@/lib/utils"; +import { type MotionProps, motion } from "motion/react"; +import { useEffect, useRef, useState } from "react"; + +interface AnimatedSpanProps extends MotionProps { + children: React.ReactNode; + delay?: number; + className?: string; +} + +export const AnimatedSpan = ({ children, delay = 0, className, ...props }: AnimatedSpanProps) => ( + + {children} + +); + +interface TypingAnimationProps extends MotionProps { + children: string; + className?: string; + duration?: number; + delay?: number; + as?: React.ElementType; +} + +export const TypingAnimation = ({ + children, + className, + duration = 60, + delay = 0, + as: Component = "span", + ...props +}: TypingAnimationProps) => { + if (typeof children !== "string") { + throw new Error("TypingAnimation: children must be a string. Received:"); + } + + const MotionComponent = motion.create(Component, { + forwardMotionProps: true, + }); + + const [displayedText, setDisplayedText] = useState(""); + const [started, setStarted] = useState(false); + const elementRef = useRef(null); + + useEffect(() => { + const startTimeout = setTimeout(() => { + setStarted(true); + }, delay); + return () => clearTimeout(startTimeout); + }, [delay]); + + useEffect(() => { + if (!started) { + return; + } + + let i = 0; + const typingEffect = setInterval(() => { + if (i < children.length) { + setDisplayedText(children.substring(0, i + 1)); + i++; + } else { + clearInterval(typingEffect); + } + }, duration); + + return () => { + clearInterval(typingEffect); + }; + }, [children, duration, started]); + + return ( + + {displayedText} + + ); +}; + +interface TerminalProps { + children: React.ReactNode; + className?: string; +} + +export const Terminal = ({ children, className }: TerminalProps) => { + return ( +
+
+
+
+
+
+
+
+
+				{children}
+			
+
+ ); +}; diff --git a/src/lib/utils.ts b/src/lib/utils.ts new file mode 100644 index 0000000..ac680b3 --- /dev/null +++ b/src/lib/utils.ts @@ -0,0 +1,6 @@ +import { type ClassValue, clsx } from "clsx"; +import { twMerge } from "tailwind-merge"; + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)); +} diff --git a/src/routes/docs/$.tsx b/src/routes/docs/$.tsx index 9d24fac..b50b419 100644 --- a/src/routes/docs/$.tsx +++ b/src/routes/docs/$.tsx @@ -17,6 +17,8 @@ import defaultMdxComponents from "fumadocs-ui/mdx"; import { baseOptions } from "@/lib/layout.shared"; import { getPageMarkdownUrl, source } from "@/lib/source"; import { Suspense } from "react"; +import { AccountRecoveryTerminal } from "@/components/account-recovery-terminal"; +import { ImageZoom } from "fumadocs-ui/components/image-zoom"; export const Route = createFileRoute("/docs/$")({ component: Page, @@ -77,6 +79,8 @@ const clientLoader = browserCollections.docs.createClientLoader({ , }} />