18 | 22 | Epic Stack 23 | 24 |
25 |26 | Check the{' '} 27 | 31 | Getting Started 32 | {' '} 33 | guide file for instructions on how to get your project off the 34 | ground! 35 |
36 | 37 |17 | {error.status} {error.data} 18 |
19 | ), 20 | statusHandlers, 21 | unexpectedErrorHandler = error =>{getErrorMessage(error)}
, 22 | }: { 23 | defaultStatusHandler?: StatusHandler 24 | statusHandlers?: Record48 | Please enter your details. 49 |
50 |115 | Hi, {data.resetPasswordUsername}. No worries. It happens all the time. 116 |
117 |Here's your verification code: ${otp}
113 |Or click the link to get started:
114 | ${onboardingUrl} 115 | 116 | 117 | `, 118 | }) 119 | 120 | if (response?.ok) { 121 | return redirect(redirectTo.pathname + redirectTo.search) 122 | } else { 123 | return json( 124 | { 125 | status: 'error', 126 | submission, 127 | } as const, 128 | { status: 500 }, 129 | ) 130 | } 131 | } 132 | 133 | export const meta: V2_MetaFunction = () => { 134 | return [{ title: 'Sign Up | Epic Notes' }] 135 | } 136 | 137 | export default function SignupRoute() { 138 | const actionData = useActionData158 | Please enter your email. 159 |
160 |139 | We've sent you a code to verify your email address. 140 |
141 |26 | Check the{' '} 27 | 31 | Getting Started 32 | {' '} 33 | guide file for instructions on how to get your project off the 34 | ground! 35 |
36 | 37 |You have enabled two-factor authentication.
57 |You have not enabled two-factor authentication yet.
74 |75 | Two factor authentication adds an extra layer of security to your 76 | account. You will need to enter a code from an authenticator app 77 | like 1Password to log in. 78 |
79 |64 | Joined {data.userJoinedDisplay} 65 |
66 |No user with the username "{params.username}" exists
109 | ), 110 | }} 111 | /> 112 | ) 113 | } 114 | 115 | export const meta: V2_MetaFunction{data.note.content}
36 |Note not found
, 54 | }} 55 | /> 56 | ) 57 | } 58 | -------------------------------------------------------------------------------- /app/routes/users+/$username_+/notes.$noteId_.edit.tsx: -------------------------------------------------------------------------------- 1 | import { json, type DataFunctionArgs } from '@remix-run/node' 2 | import { useLoaderData } from '@remix-run/react' 3 | import { NoteEditor } from '~/routes/resources+/note-editor.tsx' 4 | import { requireUserId } from '~/utils/auth.server.ts' 5 | import { prisma } from '~/utils/db.server.ts' 6 | 7 | export async function loader({ params, request }: DataFunctionArgs) { 8 | const userId = await requireUserId(request) 9 | const note = await prisma.note.findFirst({ 10 | where: { 11 | id: params.noteId, 12 | ownerId: userId, 13 | }, 14 | }) 15 | if (!note) { 16 | throw new Response('Not found', { status: 404 }) 17 | } 18 | return json({ note: note }) 19 | } 20 | 21 | export default function NoteEdit() { 22 | const data = useLoaderDataSelect a note
3 | } 4 | -------------------------------------------------------------------------------- /app/routes/users+/$username_+/notes.new.tsx: -------------------------------------------------------------------------------- 1 | import { json } from '@remix-run/router' 2 | import { type DataFunctionArgs } from '@remix-run/server-runtime' 3 | import { NoteEditor } from '~/routes/resources+/note-editor.tsx' 4 | import { requireUserId } from '~/utils/auth.server.ts' 5 | 6 | export async function loader({ request }: DataFunctionArgs) { 7 | await requireUserId(request) 8 | return json({}) 9 | } 10 | 11 | export default function NewNoteRoute() { 12 | returnNo user with the username "{params.username}" exists
123 | ), 124 | }} 125 | /> 126 | ) 127 | } 128 | -------------------------------------------------------------------------------- /app/styles/tailwind.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | -------------------------------------------------------------------------------- /app/utils/auth.server.ts: -------------------------------------------------------------------------------- 1 | import { type Password, type User } from '@prisma/client' 2 | import bcrypt from 'bcryptjs' 3 | import { Authenticator } from 'remix-auth' 4 | import { FormStrategy } from 'remix-auth-form' 5 | import invariant from 'tiny-invariant' 6 | import { prisma } from '~/utils/db.server.ts' 7 | import { sessionStorage } from './session.server.ts' 8 | import { redirect } from '@remix-run/node' 9 | 10 | export type { User } 11 | 12 | export const authenticator = new Authenticator