Skip to content

Commit

Permalink
feat: user login from icon
Browse files Browse the repository at this point in the history
Signed-off-by: Innei <tukon479@gmail.com>
  • Loading branch information
Innei committed Jun 16, 2023
1 parent fcbbb86 commit a72bfc9
Show file tree
Hide file tree
Showing 10 changed files with 189 additions and 18 deletions.
7 changes: 5 additions & 2 deletions src/app/notes/route.ts → src/app/notes/__route.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import type { NextRequest } from 'next/server'
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

import { apiClient } from '~/utils/request'

export const GET = async (request: NextRequest) => {
const url = request.nextUrl.clone()
const { data: {nid}}= await apiClient.note.getLatest()
const {
data: { nid },
} = await apiClient.note.getLatest()
url.pathname = `/notes/${nid}`
return NextResponse.redirect(url)
}
40 changes: 40 additions & 0 deletions src/app/notes/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
'use client'

import { useQuery, useQueryClient } from '@tanstack/react-query'
import { useEffect, useRef } from 'react'
import { useRouter } from 'next/navigation'

import { Loading } from '~/components/ui/loading'
import { queries } from '~/queries/definition'
import { apiClient } from '~/utils/request'

export default () => {
const { data } = useQuery(
['note', 'latest'],
async () => (await apiClient.note.getLatest()).$serialized,
{
cacheTime: 1,
},
)
const queryClient = useQueryClient()
const router = useRouter()
const onceRef = useRef(false)
useEffect(() => {
if (!data) return
if (onceRef.current) return

queryClient.setQueryData(
queries.note.byNid(data.data.nid.toString()).queryKey,
data,
)
onceRef.current = true
const id = setTimeout(() => {
router.replace(`/notes/${data.data.nid.toString()}`)
}, 1)
return () => {
clearTimeout(id)
}
}, [data])

return <Loading useDefaultLoadingText className="mt-12" />
}
2 changes: 1 addition & 1 deletion src/components/common/PageHolder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { FC } from 'react'

import { Loading } from '~/components/ui/loading'

const LoadingComponent = () => <Loading loadingText="别着急,坐和放宽" />
const LoadingComponent = () => <Loading className="mt-20" />
export const PageDataHolder = (
PageImpl: FC<any>,
useQuery: () => UseQueryResult<any>,
Expand Down
18 changes: 18 additions & 0 deletions src/components/icons/platform/GitHubBrandIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export function GitHubBrandIcon(props: React.SVGAttributes<SVGElement>) {
return (
<svg
width="1em"
height="1em"
viewBox="0 0 15 15"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M7.5 0C3.35625 0 0 3.35625 0 7.5C0 10.8187 2.14687 13.6219 5.12812 14.6156C5.50312 14.6813 5.64375 14.4563 5.64375 14.2594C5.64375 14.0813 5.63438 13.4906 5.63438 12.8625C3.75 13.2094 3.2625 12.4031 3.1125 11.9812C3.02812 11.7656 2.6625 11.1 2.34375 10.9219C2.08125 10.7812 1.70625 10.4344 2.33438 10.425C2.925 10.4156 3.34688 10.9687 3.4875 11.1937C4.1625 12.3281 5.24063 12.0094 5.67188 11.8125C5.7375 11.325 5.93437 10.9969 6.15 10.8094C4.48125 10.6219 2.7375 9.975 2.7375 7.10625C2.7375 6.29062 3.02813 5.61562 3.50625 5.09062C3.43125 4.90312 3.16875 4.13437 3.58125 3.10312C3.58125 3.10312 4.20938 2.90625 5.64375 3.87188C6.24375 3.70313 6.88125 3.61875 7.51875 3.61875C8.15625 3.61875 8.79375 3.70313 9.39375 3.87188C10.8281 2.89688 11.4563 3.10312 11.4563 3.10312C11.8688 4.13437 11.6063 4.90312 11.5313 5.09062C12.0094 5.61562 12.3 6.28125 12.3 7.10625C12.3 9.98437 10.5469 10.6219 8.87813 10.8094C9.15 11.0437 9.38438 11.4938 9.38438 12.1969C9.38438 13.2 9.375 14.0063 9.375 14.2594C9.375 14.4563 9.51563 14.6906 9.89063 14.6156C12.8531 13.6219 15 10.8094 15 7.5C15 3.35625 11.6438 0 7.5 0Z"
fill="currentColor"
/>
</svg>
)
}
28 changes: 28 additions & 0 deletions src/components/icons/platform/GoogleBrandIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
export function GoogleBrandIcon(props: React.SVGProps<SVGSVGElement>) {
return (
<svg
width="1em"
height="1em"
viewBox="0 0 15 15"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<path
d="M14.3392 7.95965C14.3392 7.49715 14.3017 7.03215 14.2217 6.57715H7.8042V9.19715H11.4792C11.3267 10.0421 10.8367 10.7896 10.1192 11.2646V12.9646H12.3117C13.5992 11.7796 14.3392 10.0296 14.3392 7.95965Z"
fill="#4285F4"
/>
<path
d="M7.80412 14.6074C9.63912 14.6074 11.1866 14.0049 12.3141 12.9649L10.1216 11.2649C9.51162 11.6799 8.72412 11.9149 7.80662 11.9149C6.03162 11.9149 4.52662 10.7174 3.98662 9.10742H1.72412V10.8599C2.87912 13.1574 5.23162 14.6074 7.80412 14.6074Z"
fill="#34A853"
/>
<path
d="M3.98375 9.1075C3.69875 8.2625 3.69875 7.3475 3.98375 6.5025V4.75H1.72375C0.75875 6.6725 0.75875 8.9375 1.72375 10.86L3.98375 9.1075Z"
fill="#FBBC04"
/>
<path
d="M7.80412 3.69296C8.77412 3.67796 9.71162 4.04296 10.4141 4.71296L12.3566 2.77046C11.1266 1.61546 9.49412 0.980458 7.80412 1.00046C5.23162 1.00046 2.87912 2.45046 1.72412 4.75046L3.98412 6.50296C4.52162 4.89046 6.02912 3.69296 7.80412 3.69296Z"
fill="#EA4335"
/>
</svg>
)
}
22 changes: 22 additions & 0 deletions src/components/icons/platform/MailIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from 'react'

export function MailIcon(props: React.SVGAttributes<SVGElement>) {
return (
<svg
width="1em"
height="1em"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<path
d="M20.4098 7.20903L17.3974 9.55205C15.4711 11.0503 14.5079 11.7994 13.4398 12.0867C12.4976 12.3401 11.5024 12.3401 10.5602 12.0867C9.49205 11.7994 8.52891 11.0503 6.60263 9.55205L3.59018 7.20903M20.4098 7.20903C19.9756 6.46813 19.3272 5.86533 18.543 5.47685C17.5804 5 16.3202 5 13.8 5H10.2C7.67976 5 6.41965 5 5.45704 5.47685C4.67282 5.86533 4.02441 6.46813 3.59018 7.20903M20.4098 7.20903C20.4444 7.26809 20.4777 7.32802 20.5095 7.38879C21 8.32466 21 9.54977 21 12C21 14.4502 21 15.6753 20.5095 16.6112C20.0781 17.4344 19.3897 18.1037 18.543 18.5232C17.5804 19 16.3202 19 13.8 19H10.2C7.67976 19 6.41965 19 5.45704 18.5232C4.61031 18.1037 3.9219 17.4344 3.49047 16.6112C3 15.6753 3 14.4502 3 12C3 9.54977 3 8.32466 3.49047 7.38879C3.52232 7.32802 3.55557 7.26809 3.59018 7.20903"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
)
}
65 changes: 56 additions & 9 deletions src/components/layout/header/internal/UserAuth.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,21 @@ import React from 'react'
import { AnimatePresence } from 'framer-motion'
import { usePathname } from 'next/navigation'

import { SignedIn, SignedOut, SignInButton, UserButton } from '@clerk/nextjs'
import {
SignedIn,
SignedOut,
SignInButton,
UserButton,
useUser,
} from '@clerk/nextjs'

import { appConfig } from '~/app.config'
import { GitHubBrandIcon } from '~/components/icons/platform/GitHubBrandIcon'
import { GoogleBrandIcon } from '~/components/icons/platform/GoogleBrandIcon'
import { MailIcon } from '~/components/icons/platform/MailIcon'
import { UserArrowLeftIcon } from '~/components/icons/user-arrow-left'
import { FloatPopover } from '~/components/ui/float-popover'
import { clsxm } from '~/utils/helper'

import { HeaderActionButton } from './HeaderActionButton'

Expand All @@ -23,14 +33,17 @@ export function UserAuth() {
<AnimatePresence>
<SignedIn key="user-info">
<div className="pointer-events-auto flex h-10 w-full items-center justify-center">
<UserButton
afterSignOutUrl={url(pathname).href}
appearance={{
elements: {
logoBox: 'w-9 h-9 ring-2 ring-white/20 rounded-full',
},
}}
/>
<div className="relative">
<UserButton
afterSignOutUrl={url(pathname).href}
appearance={{
elements: {
logoBox: 'w-9 h-9 ring-2 ring-white/20 rounded-full',
},
}}
/>
<UserAuthFromIcon className="absolute -bottom-1 -right-1" />
</div>
</div>
</SignedIn>
<SignedOut key="sign-in">
Expand All @@ -46,6 +59,40 @@ export function UserAuth() {
)
}

const UserAuthFromIcon: Component = ({ className }) => {
const { user } = useUser()
const StrategyIcon = React.useMemo(() => {
const strategy = user?.primaryEmailAddress?.verification.strategy
if (!strategy) {
return null
}

switch (strategy) {
case 'from_oauth_github':
return GitHubBrandIcon
case 'from_oauth_google':
return GoogleBrandIcon
default:
return MailIcon
}
}, [user?.primaryEmailAddress?.verification.strategy])

if (!StrategyIcon) {
return null
}

return (
<span
className={clsxm(
'pointer-events-none flex h-4 w-4 select-none items-center justify-center rounded-full bg-white dark:bg-zinc-900',
className,
)}
>
<StrategyIcon className="h-3 w-3" />
</span>
)
}

const TriggerComponent = () => {
const pathname = usePathname()
return (
Expand Down
11 changes: 9 additions & 2 deletions src/components/ui/loading/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,28 @@ import { clsxm } from '~/utils/helper'

export type LoadingProps = {
loadingText?: string
useDefaultLoadingText?: boolean
}

const defaultLoadingText = '别着急,坐和放宽'
export const Loading: Component<LoadingProps> = ({
loadingText,
className,
useDefaultLoadingText = false,
}) => {
const isClient = useIsClient()
if (!isClient) return null

const nextLoadingText = useDefaultLoadingText
? defaultLoadingText
: loadingText
return (
<div
className={clsxm('flex flex-col items-center justify-start', className)}
>
<span className="loading loading-ball loading-lg" />
{!!loadingText && <span className="mt-6 block">{loadingText}</span>}
{!!nextLoadingText && (
<span className="mt-6 block">{nextLoadingText}</span>
)}
</div>
)
}
7 changes: 5 additions & 2 deletions src/hooks/data/use-note.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const useNoteData = () => {
const nid = useNoteNId()
const { data: noteAggregation } = useQuery({
...queries.note.byNid(nid || ''),
enabled: nid !== undefined,
enabled: !!nid,
select(data) {
return data.data
},
Expand All @@ -22,5 +22,8 @@ export const useNoteNId = () => {
}

export const useNoteByNidQuery = (nid: string) => {
return useQuery(queries.note.byNid(nid))
return useQuery({
...queries.note.byNid(nid),
enabled: !!nid,
})
}
7 changes: 5 additions & 2 deletions src/queries/definition/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ export const defineQuery = <
TQueryKey extends QueryKey = QueryKey,
>(
options: FetchQueryOptions<TQueryFnData, TError, TData, TQueryKey>,
) => {
return options
): Omit<
FetchQueryOptions<TQueryFnData, TError, TData, TQueryKey>,
'queryKey'
> & { queryKey: string[] } => {
return options as any
}

0 comments on commit a72bfc9

Please sign in to comment.