From 384da1e832b622c081cc8faa0158496cc36a8e8b Mon Sep 17 00:00:00 2001 From: john Date: Sun, 18 May 2025 13:41:08 +0200 Subject: [PATCH] buttons --- src/App.tsx | 13 ++++---- src/app/api/schema.ts | 13 ++++---- src/app/auth/components/AuthNavButtons.tsx | 30 +++++++++++++++++++ src/app/auth/pages/LoginPage.tsx | 27 ++++++++++++----- src/app/auth/pages/SignupPage.tsx | 30 ++++++++++++------- src/app/feed/pages/AuthorPage.tsx | 7 +++-- src/app/feed/pages/HomePage.tsx | 9 +++--- src/app/feed/posts/postsService.ts | 8 ++++- src/components/NewPostWidget.tsx | 13 ++++---- src/components/SecondaryButton.tsx | 27 ----------------- src/components/SecondaryLinkButton.tsx | 18 ----------- src/components/SecondaryNavButton.tsx | 19 ------------ .../AnchorButton.tsx} | 7 +++-- .../{PrimaryButton.tsx => buttons/Button.tsx} | 7 +++-- src/components/buttons/LinkButton.tsx | 28 +++++++++++++++++ .../NavButton.tsx} | 10 +++++-- .../{ => inputs}/FancyTextEditor.tsx | 0 src/components/{ => inputs}/TextInput.tsx | 0 18 files changed, 150 insertions(+), 116 deletions(-) create mode 100644 src/app/auth/components/AuthNavButtons.tsx delete mode 100644 src/components/SecondaryButton.tsx delete mode 100644 src/components/SecondaryLinkButton.tsx delete mode 100644 src/components/SecondaryNavButton.tsx rename src/components/{PrimaryLinkButton.tsx => buttons/AnchorButton.tsx} (54%) rename src/components/{PrimaryButton.tsx => buttons/Button.tsx} (70%) create mode 100644 src/components/buttons/LinkButton.tsx rename src/components/{NavLinkButton.tsx => buttons/NavButton.tsx} (53%) rename src/components/{ => inputs}/FancyTextEditor.tsx (100%) rename src/components/{ => inputs}/TextInput.tsx (100%) diff --git a/src/App.tsx b/src/App.tsx index 09459fe..8b27c8b 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -9,7 +9,6 @@ import { AuthService } from './app/auth/authService.ts' import { useUser } from './app/user/userStore.ts' import LogoutPage from './app/auth/pages/LogoutPage.tsx' import UnauthorizedHandler from './app/auth/components/UnauthorizedHandler.tsx' -import Protected from './app/auth/components/Protected.tsx' function App() { const { user } = useUser() @@ -21,13 +20,11 @@ function App() { - }> - } - /> - } /> - + } + /> + } /> } /> } /> } /> diff --git a/src/app/api/schema.ts b/src/app/api/schema.ts index fcbae1c..6023ed1 100644 --- a/src/app/api/schema.ts +++ b/src/app/api/schema.ts @@ -275,6 +275,7 @@ export interface components { authorId: string content: string media: components['schemas']['CreatePostRequestMedia'][] + isPublic: boolean | null } CreatePostRequestMedia: { /** Format: uuid */ @@ -292,7 +293,7 @@ export interface components { postId: string } GetAllPublicPostsResponse: { - posts: components['schemas']['PublicPostDto'][] + posts: components['schemas']['PostDto'][] /** Format: uuid */ next: string | null } @@ -305,21 +306,21 @@ export interface components { userId: string username: string } - PublicPostAuthorDto: { + PostAuthorDto: { /** Format: uuid */ authorId: string username: string } - PublicPostDto: { - author: components['schemas']['PublicPostAuthorDto'] + PostDto: { + author: components['schemas']['PostAuthorDto'] /** Format: uuid */ postId: string content: string - media: components['schemas']['PublicPostMediaDto'][] + media: components['schemas']['PostMediaDto'][] /** Format: date-time */ createdAt: string } - PublicPostMediaDto: { + PostMediaDto: { /** Format: uri */ url: string /** Format: int32 */ diff --git a/src/app/auth/components/AuthNavButtons.tsx b/src/app/auth/components/AuthNavButtons.tsx new file mode 100644 index 0000000..33769c1 --- /dev/null +++ b/src/app/auth/components/AuthNavButtons.tsx @@ -0,0 +1,30 @@ +import { useUser } from '../../user/userStore.ts' +import NavButton from '../../../components/buttons/NavButton.tsx' +import { useLocation } from 'react-router-dom' + +export default function AuthNavButtons() { + const { user } = useUser() + + const { pathname } = useLocation() + + const redirectQuery = new URLSearchParams() + redirectQuery.set('t', pathname) + + const loggedIn = user != null + + if (loggedIn) { + return ( + <> + logout + + ) + } else { + const search = redirectQuery.toString() + return ( + <> + login + register + + ) + } +} diff --git a/src/app/auth/pages/LoginPage.tsx b/src/app/auth/pages/LoginPage.tsx index ec4f0e1..954a2cf 100644 --- a/src/app/auth/pages/LoginPage.tsx +++ b/src/app/auth/pages/LoginPage.tsx @@ -1,11 +1,13 @@ import { useRef, useState, FormEvent, useEffect } from 'react' import SingleColumnLayout from '../../../layouts/SingleColumnLayout.tsx' -import TextInput from '../../../components/TextInput.tsx' -import PrimaryButton from '../../../components/PrimaryButton.tsx' +import TextInput from '../../../components/inputs/TextInput.tsx' +import Button from '../../../components/buttons/Button.tsx' import { AuthService } from '../authService.ts' import { useNavigate } from 'react-router-dom' -import SecondaryNavButton from '../../../components/SecondaryNavButton.tsx' import { useUser } from '../../user/userStore.ts' +import NavBar from '../../../components/NavBar.tsx' +import NavButton from '../../../components/buttons/NavButton.tsx' +import LinkButton from '../../../components/buttons/LinkButton.tsx' interface LoginPageProps { authService: AuthService @@ -24,7 +26,8 @@ export default function LoginPage({ authService }: LoginPageProps) { useEffect(() => { if (user) { - navigate('/') + const search = new URLSearchParams(window.location.search) + navigate(search.get('t') || '/') } }, [user, navigate]) @@ -55,7 +58,13 @@ export default function LoginPage({ authService }: LoginPageProps) { } return ( - + + home + + } + >
@@ -86,11 +95,13 @@ export default function LoginPage({ authService }: LoginPageProps) { />
- + - register instead? + + register instead? + {error} diff --git a/src/app/auth/pages/SignupPage.tsx b/src/app/auth/pages/SignupPage.tsx index 228fc61..dbfc481 100644 --- a/src/app/auth/pages/SignupPage.tsx +++ b/src/app/auth/pages/SignupPage.tsx @@ -1,12 +1,14 @@ import { useNavigate, useParams } from 'react-router-dom' import { useEffect, useRef, useState, FormEvent, useCallback, Ref } from 'react' import SingleColumnLayout from '../../../layouts/SingleColumnLayout.tsx' -import TextInput from '../../../components/TextInput.tsx' -import PrimaryButton from '../../../components/PrimaryButton.tsx' -import PrimaryLinkButton from '../../../components/PrimaryLinkButton.tsx' +import TextInput from '../../../components/inputs/TextInput.tsx' +import Button from '../../../components/buttons/Button.tsx' +import AnchorButton from '../../../components/buttons/AnchorButton.tsx' import { invalid, valid, Validation } from '../../../utils/validation.ts' import { AuthService } from '../authService.ts' -import SecondaryNavButton from '../../../components/SecondaryNavButton.tsx' +import LinkButton from '../../../components/buttons/LinkButton.tsx' +import NavBar from '../../../components/NavBar.tsx' +import NavButton from '../../../components/buttons/NavButton.tsx' const SignupCodeKey = 'signupCode' @@ -82,7 +84,13 @@ export default function SignupPage({ authService }: SignupPageProps) { } return ( - + + home + + } + >
@@ -102,14 +110,16 @@ export default function SignupPage({ authService }: SignupPageProps) { type="password" ref={passwordInputRef} /> - {isSubmitting ? 'wait...' : 'give me an account pls'} - - login instead? + + + login instead? +
@@ -130,9 +140,9 @@ export default function SignupPage({ authService }: SignupPageProps) { If you do want to create an account, you should know who to contact

- + I'm sorry I'll go somewhere else :( - +
diff --git a/src/app/feed/pages/AuthorPage.tsx b/src/app/feed/pages/AuthorPage.tsx index 8be7f0a..d937b88 100644 --- a/src/app/feed/pages/AuthorPage.tsx +++ b/src/app/feed/pages/AuthorPage.tsx @@ -5,7 +5,8 @@ import { useParams } from 'react-router-dom' import SingleColumnLayout from '../../../layouts/SingleColumnLayout.tsx' import NavBar from '../../../components/NavBar.tsx' import { useFeedViewModel } from '../components/FeedView.ts' -import NavLinkButton from '../../../components/NavLinkButton.tsx' +import NavButton from '../../../components/buttons/NavButton.tsx' +import AuthNavButtons from '../../auth/components/AuthNavButtons.tsx' interface AuthorPageParams { postsService: PostsService @@ -27,8 +28,8 @@ export default function AuthorPage({ postsService }: AuthorPageParams) { - home - logout + home + } > diff --git a/src/app/feed/pages/HomePage.tsx b/src/app/feed/pages/HomePage.tsx index 3659dae..5ce323d 100644 --- a/src/app/feed/pages/HomePage.tsx +++ b/src/app/feed/pages/HomePage.tsx @@ -9,7 +9,7 @@ import { Post } from '../posts/posts.ts' import { Temporal } from '@js-temporal/polyfill' import SingleColumnLayout from '../../../layouts/SingleColumnLayout.tsx' import NavBar from '../../../components/NavBar.tsx' -import NavLinkButton from '../../../components/NavLinkButton.tsx' +import AuthNavButtons from '../../auth/components/AuthNavButtons.tsx' interface HomePageProps { postsService: PostsService @@ -18,7 +18,6 @@ interface HomePageProps { export default function HomePage({ postsService, mediaService }: HomePageProps) { const { user } = useUser() - const [isSubmitting, setIsSubmitting] = useState(false) const fetchPosts = useCallback( @@ -59,16 +58,18 @@ export default function HomePage({ postsService, mediaService }: HomePageProps) [mediaService, postsService, setPages, user], ) + const isLoggedIn = user != null + return ( - logout + } >
- + {isLoggedIn && }
diff --git a/src/app/feed/posts/postsService.ts b/src/app/feed/posts/postsService.ts index 78c90c4..f7da251 100644 --- a/src/app/feed/posts/postsService.ts +++ b/src/app/feed/posts/postsService.ts @@ -4,7 +4,12 @@ import client from '../../api/client.ts' export class PostsService { constructor() {} - async createNew(authorId: string, content: string, media: CreatePostMedia[]): Promise { + async createNew( + authorId: string, + content: string, + media: CreatePostMedia[], + isPublic: boolean, + ): Promise { const response = await client.POST('/posts', { body: { authorId, @@ -12,6 +17,7 @@ export class PostsService { media: media.map((m) => { return { ...m, type: null, url: m.url.toString() } }), + isPublic, }, credentials: 'include', }) diff --git a/src/components/NewPostWidget.tsx b/src/components/NewPostWidget.tsx index 9d139bf..41b6920 100644 --- a/src/components/NewPostWidget.tsx +++ b/src/components/NewPostWidget.tsx @@ -1,7 +1,6 @@ import { useState } from 'react' -import FancyTextEditor, { TextInputKeyDownEvent } from './FancyTextEditor.tsx' -import PrimaryButton from './PrimaryButton.tsx' -import SecondaryButton from './SecondaryButton.tsx' +import FancyTextEditor, { TextInputKeyDownEvent } from './inputs/FancyTextEditor.tsx' +import Button from './buttons/Button.tsx' import { openFileDialog } from '../utils/openFileDialog.ts' interface NewPostWidgetProps { @@ -86,13 +85,15 @@ export default function NewPostWidget({ onSubmit, isSubmitting = false }: NewPos )}
- + add media - + + add media + +
) diff --git a/src/components/SecondaryButton.tsx b/src/components/SecondaryButton.tsx deleted file mode 100644 index 24b80b2..0000000 --- a/src/components/SecondaryButton.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { PropsWithChildren } from 'react' -interface PrimaryButtonProps { - disabled?: boolean - type?: 'submit' | 'button' - onClick?: () => void - className?: string -} - -export default function SecondaryButton({ - disabled = false, - type = 'button', - onClick = () => {}, - className: extraClasses = '', - children, -}: PropsWithChildren) { - return ( - - ) -} diff --git a/src/components/SecondaryLinkButton.tsx b/src/components/SecondaryLinkButton.tsx deleted file mode 100644 index 1e77c0f..0000000 --- a/src/components/SecondaryLinkButton.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { PropsWithChildren } from 'react' - -interface SecondaryLinkButtonProps { - href: string - className?: string -} - -export default function SecondaryLinkButton({ - href, - className: extraClasses = '', - children, -}: PropsWithChildren) { - return ( - - {children} - - ) -} diff --git a/src/components/SecondaryNavButton.tsx b/src/components/SecondaryNavButton.tsx deleted file mode 100644 index bd8f542..0000000 --- a/src/components/SecondaryNavButton.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import { PropsWithChildren } from 'react' -import { Link } from 'react-router-dom' - -interface SecondaryNavButtonProps { - to: string - className?: string -} - -export default function SecondaryNavButton({ - to, - className: extraClasses = '', - children, -}: PropsWithChildren) { - return ( - - {children} - - ) -} diff --git a/src/components/PrimaryLinkButton.tsx b/src/components/buttons/AnchorButton.tsx similarity index 54% rename from src/components/PrimaryLinkButton.tsx rename to src/components/buttons/AnchorButton.tsx index 1d3ee8a..107ad66 100644 --- a/src/components/PrimaryLinkButton.tsx +++ b/src/components/buttons/AnchorButton.tsx @@ -3,15 +3,18 @@ import { PropsWithChildren } from 'react' interface PrimaryLinkButtonProps { href: string className?: string + secondary?: boolean } -export default function PrimaryLinkButton({ +export default function AnchorButton({ href, className: extraClasses = '', children, + secondary = false, }: PropsWithChildren) { + const klass = secondary ? 'secondary-button' : 'primary-button' return ( - + {children} ) diff --git a/src/components/PrimaryButton.tsx b/src/components/buttons/Button.tsx similarity index 70% rename from src/components/PrimaryButton.tsx rename to src/components/buttons/Button.tsx index 1430e1e..282462e 100644 --- a/src/components/PrimaryButton.tsx +++ b/src/components/buttons/Button.tsx @@ -5,21 +5,24 @@ interface PrimaryButtonProps { type?: 'submit' | 'button' onClick?: () => void className?: string + secondary?: boolean } -export default function PrimaryButton({ +export default function Button({ disabled = false, type = 'button', onClick = () => {}, className: extraClasses = '', children, + secondary = false, }: PropsWithChildren) { + const klass = secondary ? 'secondary-button' : 'primary-button' return ( diff --git a/src/components/buttons/LinkButton.tsx b/src/components/buttons/LinkButton.tsx new file mode 100644 index 0000000..3571cff --- /dev/null +++ b/src/components/buttons/LinkButton.tsx @@ -0,0 +1,28 @@ +import { PropsWithChildren } from 'react' +import { Link } from 'react-router-dom' + +interface LinkButtonProps { + to: string | To + className?: string + secondary?: boolean +} + +interface To { + pathname: string + search?: string + hash?: string +} + +export default function LinkButton({ + to, + className: extraClasses = '', + secondary = false, + children, +}: PropsWithChildren) { + const klass = secondary ? 'secondary-button' : 'primary-button' + return ( + + {children} + + ) +} diff --git a/src/components/NavLinkButton.tsx b/src/components/buttons/NavButton.tsx similarity index 53% rename from src/components/NavLinkButton.tsx rename to src/components/buttons/NavButton.tsx index 890aa16..fd2fe67 100644 --- a/src/components/NavLinkButton.tsx +++ b/src/components/buttons/NavButton.tsx @@ -1,10 +1,16 @@ import { PropsWithChildren } from 'react' import { Link } from 'react-router-dom' interface NavLinkButtonProps { - to: string + to: string | To } -export default function NavLinkButton({ to, children }: PropsWithChildren) { +interface To { + pathname: string + search?: string + hash?: string +} + +export default function NavButton({ to, children }: PropsWithChildren) { return ( {children} diff --git a/src/components/FancyTextEditor.tsx b/src/components/inputs/FancyTextEditor.tsx similarity index 100% rename from src/components/FancyTextEditor.tsx rename to src/components/inputs/FancyTextEditor.tsx diff --git a/src/components/TextInput.tsx b/src/components/inputs/TextInput.tsx similarity index 100% rename from src/components/TextInput.tsx rename to src/components/inputs/TextInput.tsx