From 338d9e3d081b7a4ad62c63b9da5ee8df2ea399ca Mon Sep 17 00:00:00 2001 From: Igor Lobanov Date: Mon, 14 Nov 2022 11:02:08 +0100 Subject: [PATCH] code review --- src/components/Article/FullArticle.tsx | 4 +-- src/components/Article/SharePopup.tsx | 6 ++-- src/components/Author/Card.tsx | 4 +-- src/components/Feed/Sidebar.tsx | 4 +-- src/components/Nav/AuthModal/EmailConfirm.tsx | 4 +-- .../Nav/AuthModal/ForgotPasswordForm.tsx | 2 +- src/components/Nav/AuthModal/LoginForm.tsx | 5 +-- src/components/Nav/AuthModal/RegisterForm.tsx | 2 +- src/components/Nav/HeaderAuth.tsx | 14 +++----- src/components/Nav/ProfileModal.tsx | 4 +-- src/components/Nav/ProfilePopup.tsx | 9 ++--- src/components/Root.tsx | 6 ++-- src/components/Topic/Card.tsx | 4 +-- src/components/Topic/Full.tsx | 4 +-- src/components/Views/AllAuthors.tsx | 4 +-- src/components/Views/AllTopics.tsx | 4 +-- src/components/Views/Create.tsx | 12 ++----- src/components/Views/Feed.tsx | 4 +-- src/components/_shared/ClientContainer.tsx | 12 +++++++ .../{Nav => _shared}/Popup.module.scss | 0 src/components/{Nav => _shared}/Popup.tsx | 0 src/context/{auth.tsx => session.tsx} | 34 ++++--------------- src/stores/auth.ts | 21 ++++++++++++ 23 files changed, 85 insertions(+), 78 deletions(-) create mode 100644 src/components/_shared/ClientContainer.tsx rename src/components/{Nav => _shared}/Popup.module.scss (100%) rename src/components/{Nav => _shared}/Popup.tsx (100%) rename src/context/{auth.tsx => session.tsx} (73%) create mode 100644 src/stores/auth.ts diff --git a/src/components/Article/FullArticle.tsx b/src/components/Article/FullArticle.tsx index 717aff64..d521c250 100644 --- a/src/components/Article/FullArticle.tsx +++ b/src/components/Article/FullArticle.tsx @@ -10,7 +10,7 @@ import { showModal } from '../../stores/ui' import { incrementView } from '../../stores/zine/articles' import MD from './MD' import { SharePopup } from './SharePopup' -import { useAuth } from '../../context/auth' +import { useSession } from '../../context/session' const MAX_COMMENT_LEVEL = 6 @@ -38,7 +38,7 @@ const formatDate = (date: Date) => { } export const FullArticle = (props: ArticleProps) => { - const { session } = useAuth() + const { session } = useSession() onMount(() => { incrementView({ articleSlug: props.article.slug }) diff --git a/src/components/Article/SharePopup.tsx b/src/components/Article/SharePopup.tsx index 851cf599..fe0de743 100644 --- a/src/components/Article/SharePopup.tsx +++ b/src/components/Article/SharePopup.tsx @@ -1,7 +1,9 @@ import { Icon } from '../Nav/Icon' -import styles from '../Nav/Popup.module.scss' import { t } from '../../utils/intl' -import { Popup, PopupProps } from '../Nav/Popup' + +import styles from '../_shared/Popup.module.scss' +import type { PopupProps } from '../_shared/Popup' +import { Popup } from '../_shared/Popup' type SharePopupProps = Omit diff --git a/src/components/Author/Card.tsx b/src/components/Author/Card.tsx index 7cfa677d..4115eda1 100644 --- a/src/components/Author/Card.tsx +++ b/src/components/Author/Card.tsx @@ -8,7 +8,7 @@ import { t } from '../../utils/intl' import { locale } from '../../stores/ui' import { follow, unfollow } from '../../stores/zine/common' import { clsx } from 'clsx' -import { useAuth } from '../../context/auth' +import { useSession } from '../../context/session' interface AuthorCardProps { compact?: boolean @@ -23,7 +23,7 @@ interface AuthorCardProps { } export const AuthorCard = (props: AuthorCardProps) => { - const { session } = useAuth() + const { session } = useSession() const subscribed = createMemo( () => session()?.news?.authors?.some((u) => u === props.author.slug) || false diff --git a/src/components/Feed/Sidebar.tsx b/src/components/Feed/Sidebar.tsx index 31b8858c..1dc4edc1 100644 --- a/src/components/Feed/Sidebar.tsx +++ b/src/components/Feed/Sidebar.tsx @@ -6,7 +6,7 @@ import { Icon } from '../Nav/Icon' import { useTopicsStore } from '../../stores/zine/topics' import { useArticlesStore } from '../../stores/zine/articles' import { useSeenStore } from '../../stores/zine/seen' -import { useAuth } from '../../context/auth' +import { useSession } from '../../context/session' type FeedSidebarProps = { authors: Author[] @@ -14,7 +14,7 @@ type FeedSidebarProps = { export const FeedSidebar = (props: FeedSidebarProps) => { const { getSeen: seen } = useSeenStore() - const { session } = useAuth() + const { session } = useSession() const { authorEntities } = useAuthorsStore({ authors: props.authors }) const { articlesByTopic } = useArticlesStore() const { topicEntities } = useTopicsStore() diff --git a/src/components/Nav/AuthModal/EmailConfirm.tsx b/src/components/Nav/AuthModal/EmailConfirm.tsx index 7525bdf2..b734d23d 100644 --- a/src/components/Nav/AuthModal/EmailConfirm.tsx +++ b/src/components/Nav/AuthModal/EmailConfirm.tsx @@ -5,14 +5,14 @@ import { hideModal } from '../../../stores/ui' import { createMemo, createSignal, onMount, Show } from 'solid-js' import { handleClientRouteLinkClick, useRouter } from '../../../stores/router' import type { ConfirmEmailSearchParams } from './types' -import { useAuth } from '../../../context/auth' import { ApiError } from '../../../utils/apiClient' +import { useSession } from '../../../context/session' export const EmailConfirm = () => { const { session, actions: { confirmEmail } - } = useAuth() + } = useSession() const [isTokenExpired, setIsTokenExpired] = createSignal(false) const [isTokenInvalid, setIsTokenInvalid] = createSignal(false) diff --git a/src/components/Nav/AuthModal/ForgotPasswordForm.tsx b/src/components/Nav/AuthModal/ForgotPasswordForm.tsx index 81116779..6a92582b 100644 --- a/src/components/Nav/AuthModal/ForgotPasswordForm.tsx +++ b/src/components/Nav/AuthModal/ForgotPasswordForm.tsx @@ -7,8 +7,8 @@ import { email, setEmail } from './sharedLogic' import type { AuthModalSearchParams } from './types' import { isValidEmail } from './validators' import { locale } from '../../../stores/ui' -import { signSendLink } from '../../../context/auth' import { ApiError } from '../../../utils/apiClient' +import { signSendLink } from '../../../stores/auth' type FormFields = { email: string diff --git a/src/components/Nav/AuthModal/LoginForm.tsx b/src/components/Nav/AuthModal/LoginForm.tsx index 50669263..89f98d66 100644 --- a/src/components/Nav/AuthModal/LoginForm.tsx +++ b/src/components/Nav/AuthModal/LoginForm.tsx @@ -9,7 +9,8 @@ import { email, setEmail } from './sharedLogic' import { useRouter } from '../../../stores/router' import type { AuthModalSearchParams } from './types' import { hideModal, locale } from '../../../stores/ui' -import { signSendLink, useAuth } from '../../../context/auth' +import { useSession } from '../../../context/session' +import { signSendLink } from '../../../stores/auth' type FormFields = { email: string @@ -28,7 +29,7 @@ export const LoginForm = () => { const { actions: { signIn } - } = useAuth() + } = useSession() const { changeSearchParam } = useRouter() diff --git a/src/components/Nav/AuthModal/RegisterForm.tsx b/src/components/Nav/AuthModal/RegisterForm.tsx index d936f659..b5f56fb7 100644 --- a/src/components/Nav/AuthModal/RegisterForm.tsx +++ b/src/components/Nav/AuthModal/RegisterForm.tsx @@ -11,7 +11,7 @@ import { useRouter } from '../../../stores/router' import type { AuthModalSearchParams } from './types' import { hideModal } from '../../../stores/ui' import { checkEmail, useEmailChecks } from '../../../stores/emailChecks' -import { register } from '../../../context/auth' +import { register } from '../../../stores/auth' type FormFields = { name: string diff --git a/src/components/Nav/HeaderAuth.tsx b/src/components/Nav/HeaderAuth.tsx index 970d9005..a98566d8 100644 --- a/src/components/Nav/HeaderAuth.tsx +++ b/src/components/Nav/HeaderAuth.tsx @@ -9,19 +9,19 @@ import { ProfilePopup } from './ProfilePopup' import Userpic from '../Author/Userpic' import type { Author } from '../../graphql/types.gen' import { showModal, useWarningsStore } from '../../stores/ui' -import { useAuth } from '../../context/auth' +import { ClientContainer } from '../_shared/ClientContainer' +import { useSession } from '../../context/session' type HeaderAuthProps = { setIsProfilePopupVisible: (value: boolean) => void } export const HeaderAuth = (props: HeaderAuthProps) => { - const [isMounted, setIsMounted] = createSignal(false) const { page } = useRouter() const [visibleWarnings, setVisibleWarnings] = createSignal(false) const { warnings } = useWarningsStore() - const { session, isAuthenticated } = useAuth() + const { session, isAuthenticated } = useSession() const toggleWarnings = () => setVisibleWarnings(!visibleWarnings()) @@ -36,12 +36,8 @@ export const HeaderAuth = (props: HeaderAuthProps) => { toggleWarnings() } - onMount(() => { - setIsMounted(true) - }) - return ( - +
@@ -106,6 +102,6 @@ export const HeaderAuth = (props: HeaderAuthProps) => {
-
+ ) } diff --git a/src/components/Nav/ProfileModal.tsx b/src/components/Nav/ProfileModal.tsx index 10b69d7f..ddfabe87 100644 --- a/src/components/Nav/ProfileModal.tsx +++ b/src/components/Nav/ProfileModal.tsx @@ -3,13 +3,13 @@ import type { Author } from '../../graphql/types.gen' import { t } from '../../utils/intl' import { hideModal } from '../../stores/ui' import { createMemo, For } from 'solid-js' -import { useAuth } from '../../context/auth' +import { useSession } from '../../context/session' export const ProfileModal = () => { const { session, actions: { signOut } - } = useAuth() + } = useSession() const quit = () => { signOut() diff --git a/src/components/Nav/ProfilePopup.tsx b/src/components/Nav/ProfilePopup.tsx index f0fb7772..807b0cdd 100644 --- a/src/components/Nav/ProfilePopup.tsx +++ b/src/components/Nav/ProfilePopup.tsx @@ -1,6 +1,7 @@ -import { Popup, PopupProps } from './Popup' -import styles from './Popup.module.scss' -import { useAuth } from '../../context/auth' +import { useSession } from '../../context/session' +import type { PopupProps } from '../_shared/Popup' +import { Popup } from '../_shared/Popup' +import styles from '../_shared/Popup.module.scss' type ProfilePopupProps = Omit @@ -8,7 +9,7 @@ export const ProfilePopup = (props: ProfilePopupProps) => { const { session, actions: { signOut } - } = useAuth() + } = useSession() return ( diff --git a/src/components/Root.tsx b/src/components/Root.tsx index 787bcca1..46efc845 100644 --- a/src/components/Root.tsx +++ b/src/components/Root.tsx @@ -29,7 +29,7 @@ import { TermsOfUsePage } from './Pages/about/TermsOfUsePage' import { ThanksPage } from './Pages/about/ThanksPage' import { CreatePage } from './Pages/CreatePage' import { ConnectPage } from './Pages/ConnectPage' -import { AuthProvider } from '../context/auth' +import { SessionProvider } from '../context/session' // TODO: lazy load // const HomePage = lazy(() => import('./Pages/HomePage')) @@ -103,8 +103,8 @@ export const Root = (props: PageProps) => { } return ( - + - + ) } diff --git a/src/components/Topic/Card.tsx b/src/components/Topic/Card.tsx index ffcf8b9f..0b153cbe 100644 --- a/src/components/Topic/Card.tsx +++ b/src/components/Topic/Card.tsx @@ -8,7 +8,7 @@ import { locale } from '../../stores/ui' import { follow, unfollow } from '../../stores/zine/common' import { getLogger } from '../../utils/logger' import { clsx } from 'clsx' -import { useAuth } from '../../context/auth' +import { useSession } from '../../context/session' const log = getLogger('TopicCard') @@ -24,7 +24,7 @@ interface TopicProps { } export const TopicCard = (props: TopicProps) => { - const { session } = useAuth() + const { session } = useSession() const subscribed = createMemo(() => { if (!session()?.user?.slug || !session()?.news?.topics) { diff --git a/src/components/Topic/Full.tsx b/src/components/Topic/Full.tsx index 70d78da8..86c48852 100644 --- a/src/components/Topic/Full.tsx +++ b/src/components/Topic/Full.tsx @@ -5,14 +5,14 @@ import styles from './Full.module.scss' import { follow, unfollow } from '../../stores/zine/common' import { t } from '../../utils/intl' import { clsx } from 'clsx' -import { useAuth } from '../../context/auth' +import { useSession } from '../../context/session' type Props = { topic: Topic } export const FullTopic = (props: Props) => { - const { session } = useAuth() + const { session } = useSession() const subscribed = createMemo(() => session()?.news?.topics?.includes(props.topic?.slug)) return ( diff --git a/src/components/Views/AllAuthors.tsx b/src/components/Views/AllAuthors.tsx index eec96c19..99fedb64 100644 --- a/src/components/Views/AllAuthors.tsx +++ b/src/components/Views/AllAuthors.tsx @@ -7,7 +7,7 @@ import { useAuthorsStore, setAuthorsSort } from '../../stores/zine/authors' import { handleClientRouteLinkClick, useRouter } from '../../stores/router' import styles from '../../styles/AllTopics.module.scss' import { clsx } from 'clsx' -import { useAuth } from '../../context/auth' +import { useSession } from '../../context/session' type AllAuthorsPageSearchParams = { by: '' | 'name' | 'shouts' | 'rating' @@ -23,7 +23,7 @@ export const AllAuthorsView = (props: Props) => { const { sortedAuthors } = useAuthorsStore({ authors: props.authors }) const [limit, setLimit] = createSignal(PAGE_SIZE) - const { session } = useAuth() + const { session } = useSession() createEffect(() => { setAuthorsSort(searchParams().by || 'shouts') diff --git a/src/components/Views/AllTopics.tsx b/src/components/Views/AllTopics.tsx index 2261a10c..d94461f4 100644 --- a/src/components/Views/AllTopics.tsx +++ b/src/components/Views/AllTopics.tsx @@ -7,7 +7,7 @@ import { handleClientRouteLinkClick, useRouter } from '../../stores/router' import { TopicCard } from '../Topic/Card' import styles from '../../styles/AllTopics.module.scss' import { clsx } from 'clsx' -import { useAuth } from '../../context/auth' +import { useSession } from '../../context/session' type AllTopicsPageSearchParams = { by: 'shouts' | 'authors' | 'title' | '' @@ -28,7 +28,7 @@ export const AllTopicsView = (props: AllTopicsViewProps) => { sortBy: searchParams().by || 'shouts' }) - const { session } = useAuth() + const { session } = useSession() createEffect(() => { setTopicsSort(searchParams().by || 'shouts') diff --git a/src/components/Views/Create.tsx b/src/components/Views/Create.tsx index 2281ddf5..636b1386 100644 --- a/src/components/Views/Create.tsx +++ b/src/components/Views/Create.tsx @@ -1,17 +1,11 @@ -import { Show, onMount, createSignal } from 'solid-js' import { Editor } from '../EditorNew/Editor' +import { ClientContainer } from '../_shared/ClientContainer' export const CreateView = () => { - // don't render anything on server - // usage of isServer causing hydration errors - const [isMounted, setIsMounted] = createSignal(false) - - onMount(() => setIsMounted(true)) - return ( - + - + ) } diff --git a/src/components/Views/Feed.tsx b/src/components/Views/Feed.tsx index 36318f12..aca7987b 100644 --- a/src/components/Views/Feed.tsx +++ b/src/components/Views/Feed.tsx @@ -14,7 +14,7 @@ import { useReactionsStore } from '../../stores/zine/reactions' import { useAuthorsStore } from '../../stores/zine/authors' import { useTopicsStore } from '../../stores/zine/topics' import { useTopAuthorsStore } from '../../stores/zine/topAuthors' -import { useAuth } from '../../context/auth' +import { useSession } from '../../context/session' // const AUTHORSHIP_REACTIONS = [ // ReactionKind.Accept, @@ -32,7 +32,7 @@ export const FeedView = () => { const { sortedAuthors } = useAuthorsStore() const { topTopics } = useTopicsStore() const { topAuthors } = useTopAuthorsStore() - const { session } = useAuth() + const { session } = useSession() const topReactions = createMemo(() => sortBy(reactions(), byCreated)) diff --git a/src/components/_shared/ClientContainer.tsx b/src/components/_shared/ClientContainer.tsx new file mode 100644 index 00000000..913efae6 --- /dev/null +++ b/src/components/_shared/ClientContainer.tsx @@ -0,0 +1,12 @@ +import type { JSX } from 'solid-js' +import { createSignal, onMount, Show } from 'solid-js' + +// show children only on client side +// usage of isServer causing hydration errors +export const ClientContainer = (props: { children: JSX.Element }) => { + const [isMounted, setIsMounted] = createSignal(false) + + onMount(() => setIsMounted(true)) + + return {props.children} +} diff --git a/src/components/Nav/Popup.module.scss b/src/components/_shared/Popup.module.scss similarity index 100% rename from src/components/Nav/Popup.module.scss rename to src/components/_shared/Popup.module.scss diff --git a/src/components/Nav/Popup.tsx b/src/components/_shared/Popup.tsx similarity index 100% rename from src/components/Nav/Popup.tsx rename to src/components/_shared/Popup.tsx diff --git a/src/context/auth.tsx b/src/context/session.tsx similarity index 73% rename from src/context/auth.tsx rename to src/context/session.tsx index 71792145..47a51e76 100644 --- a/src/context/auth.tsx +++ b/src/context/session.tsx @@ -4,7 +4,7 @@ import type { AuthResult } from '../graphql/types.gen' import { apiClient } from '../utils/apiClient' import { resetToken, setToken } from '../graphql/privateGraphQLClient' -type AuthContextType = { +type SessionContextType = { session: InitializedResource isAuthenticated: Accessor actions: { @@ -15,7 +15,7 @@ type AuthContextType = { } } -const AuthContext = createContext() +const SessionContext = createContext() const refreshSession = async (): Promise => { try { @@ -32,31 +32,11 @@ const refreshSession = async (): Promise => { } } -export const register = async ({ - name, - email, - password -}: { - name: string - email: string - password: string -}) => { - await apiClient.authRegister({ - name, - email, - password - }) +export function useSession() { + return useContext(SessionContext) } -export const signSendLink = async ({ email, lang }: { email: string; lang: string }) => { - return await apiClient.authSendLink({ email, lang }) -} - -export function useAuth() { - return useContext(AuthContext) -} - -export const AuthProvider = (props: { children: JSX.Element }) => { +export const SessionProvider = (props: { children: JSX.Element }) => { const [session, { refetch: refetchRefreshSession, mutate }] = createResource(refreshSession, { ssrLoadFrom: 'initial', initialValue: null @@ -91,11 +71,11 @@ export const AuthProvider = (props: { children: JSX.Element }) => { confirmEmail } - const value: AuthContextType = { session, isAuthenticated, actions } + const value: SessionContextType = { session, isAuthenticated, actions } onMount(() => { refetchRefreshSession() }) - return {props.children} + return {props.children} } diff --git a/src/stores/auth.ts b/src/stores/auth.ts new file mode 100644 index 00000000..b92814fa --- /dev/null +++ b/src/stores/auth.ts @@ -0,0 +1,21 @@ +import { apiClient } from '../utils/apiClient' + +export const register = async ({ + name, + email, + password +}: { + name: string + email: string + password: string +}) => { + await apiClient.authRegister({ + name, + email, + password + }) +} + +export const signSendLink = async ({ email, lang }: { email: string; lang: string }) => { + return await apiClient.authSendLink({ email, lang }) +}