signup page
This commit is contained in:
parent
82361fdf63
commit
2f330a3b40
4 changed files with 105 additions and 4 deletions
|
@ -3,6 +3,7 @@ import HomePage from './pages/HomePage.tsx'
|
||||||
import { PostsService } from './model/posts/postsService.ts'
|
import { PostsService } from './model/posts/postsService.ts'
|
||||||
import AuthorPage from './pages/AuthorPage.tsx'
|
import AuthorPage from './pages/AuthorPage.tsx'
|
||||||
import { MediaService } from './model/mediaService.ts'
|
import { MediaService } from './model/mediaService.ts'
|
||||||
|
import SignupPage from './pages/SignupPage.tsx'
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const postService = new PostsService()
|
const postService = new PostsService()
|
||||||
|
@ -15,6 +16,7 @@ function App() {
|
||||||
element={<HomePage postsService={postService} mediaService={mediaService} />}
|
element={<HomePage postsService={postService} mediaService={mediaService} />}
|
||||||
/>
|
/>
|
||||||
<Route path="/u/:username" element={<AuthorPage postsService={postService} />} />
|
<Route path="/u/:username" element={<AuthorPage postsService={postService} />} />
|
||||||
|
<Route path="/signup" element={<SignupPage />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
)
|
)
|
||||||
|
|
15
src/layouts/AppLayout.tsx
Normal file
15
src/layouts/AppLayout.tsx
Normal 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>
|
||||||
|
)
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ import NewPostWidget from '../components/NewPostWidget.tsx'
|
||||||
import { useFeedViewModel } from '../feed/feedViewModel.ts'
|
import { useFeedViewModel } from '../feed/feedViewModel.ts'
|
||||||
import { Post } from '../model/posts/posts.ts'
|
import { Post } from '../model/posts/posts.ts'
|
||||||
import { Temporal } from '@js-temporal/polyfill'
|
import { Temporal } from '@js-temporal/polyfill'
|
||||||
|
import AppLayout from '../layouts/AppLayout.tsx'
|
||||||
|
|
||||||
interface HomePageProps {
|
interface HomePageProps {
|
||||||
postsService: PostsService
|
postsService: PostsService
|
||||||
|
@ -48,9 +49,11 @@ export default function HomePage({ postsService, mediaService }: HomePageProps)
|
||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<AppLayout>
|
||||||
<main className={`w-full max-w-3xl mx-auto`}>
|
<main className={`w-full max-w-3xl mx-auto`}>
|
||||||
<NewPostWidget onSubmit={onCreatePost} isSubmitting={isSubmitting} />
|
<NewPostWidget onSubmit={onCreatePost} isSubmitting={isSubmitting} />
|
||||||
<FeedView pages={pages} onLoadMore={loadNextPage} />
|
<FeedView pages={pages} onLoadMore={loadNextPage} />
|
||||||
</main>
|
</main>
|
||||||
|
</AppLayout>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
81
src/pages/SignupPage.tsx
Normal file
81
src/pages/SignupPage.tsx
Normal 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>
|
||||||
|
)
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue