signup page

This commit is contained in:
john 2025-05-05 23:20:31 +02:00
parent 82361fdf63
commit 2f330a3b40
4 changed files with 105 additions and 4 deletions

View file

@ -3,6 +3,7 @@ import HomePage from './pages/HomePage.tsx'
import { PostsService } from './model/posts/postsService.ts'
import AuthorPage from './pages/AuthorPage.tsx'
import { MediaService } from './model/mediaService.ts'
import SignupPage from './pages/SignupPage.tsx'
function App() {
const postService = new PostsService()
@ -15,6 +16,7 @@ function App() {
element={<HomePage postsService={postService} mediaService={mediaService} />}
/>
<Route path="/u/:username" element={<AuthorPage postsService={postService} />} />
<Route path="/signup" element={<SignupPage />} />
</Routes>
</BrowserRouter>
)

15
src/layouts/AppLayout.tsx Normal file
View file

@ -0,0 +1,15 @@
import { PropsWithChildren } from 'react'
import { Link } from 'react-router'
export default function AppLayout({ children }: PropsWithChildren) {
return (
<div>
<nav className={`w-full flex flex-row-reverse px-4 md:px-8 py-0.5`}>
<Link className={`text-gray-800`} to="/signup">
create account
</Link>
</nav>
<main className={`w-full`}>{children}</main>
</div>
)
}

View file

@ -7,6 +7,7 @@ import NewPostWidget from '../components/NewPostWidget.tsx'
import { useFeedViewModel } from '../feed/feedViewModel.ts'
import { Post } from '../model/posts/posts.ts'
import { Temporal } from '@js-temporal/polyfill'
import AppLayout from '../layouts/AppLayout.tsx'
interface HomePageProps {
postsService: PostsService
@ -48,9 +49,11 @@ export default function HomePage({ postsService, mediaService }: HomePageProps)
)
return (
<main className={`w-full max-w-3xl mx-auto`}>
<NewPostWidget onSubmit={onCreatePost} isSubmitting={isSubmitting} />
<FeedView pages={pages} onLoadMore={loadNextPage} />
</main>
<AppLayout>
<main className={`w-full max-w-3xl mx-auto`}>
<NewPostWidget onSubmit={onCreatePost} isSubmitting={isSubmitting} />
<FeedView pages={pages} onLoadMore={loadNextPage} />
</main>
</AppLayout>
)
}

81
src/pages/SignupPage.tsx Normal file
View file

@ -0,0 +1,81 @@
import { useSearchParams } from 'react-router'
import { useState } from 'react'
export default function SignupPage() {
const [searchParams] = useSearchParams()
const signupCode = searchParams.get('c')
const [isSubmitting, setIsSubmitting] = useState(false)
if (!signupCode) {
return <RejectionMessage />
}
return (
<main className="w-full max-w-3xl mx-auto p-4">
<div className="mt-12">
<form className="flex flex-col gap-4 max-w-md" onSubmit={(e) => e.preventDefault()}>
<div className="flex flex-col gap-2">
<label htmlFor="username" className="text-sm text-gray-600">
Username
</label>
<input
id="username"
type="text"
className="p-2 border rounded bg-white/50 focus:outline-none focus:border-gray-400"
required
/>
</div>
<div className="flex flex-col gap-2">
<label htmlFor="email" className="text-sm text-gray-600">
Email (optional)
</label>
<input
id="email"
type="email"
className="p-2 border rounded bg-white/50 focus:outline-none focus:border-gray-400"
/>
</div>
<div className="flex flex-col gap-2">
<label htmlFor="password" className="text-sm text-gray-600">
Password
</label>
<input
id="password"
type="password"
className="p-2 border rounded bg-white/50 focus:outline-none focus:border-gray-400"
required
/>
</div>
<button
type="submit"
disabled={isSubmitting}
className="mt-4 p-2 bg-gray-800 text-white rounded hover:bg-gray-700 disabled:opacity-50 disabled:cursor-not-allowed"
>
{isSubmitting ? 'Creating account...' : 'Create account'}
</button>
</form>
</div>
</main>
)
}
function RejectionMessage() {
return (
<main className="w-full max-w-3xl mx-auto p-4">
<div className="mt-12 text-gray-600 flex flex-col gap-2">
<p>An invitation is required to create an account.</p>
<p>
I'm surprised you even found your way here without one and honestly I'd prefer it if you
would leave
</p>
<p>
If you <span className="italic">do</span> want to create an account, you should know who
to contact
</p>
</div>
</main>
)
}