Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/app/auth/auth-v4/emailEntry.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
'use client'
import InputField from '@annatarhe/lake-ui/form-input-field'
import { useAutoAnimate } from '@formkit/auto-animate/react'
import { ChevronRight } from 'lucide-react'
import { zodResolver } from '@hookform/resolvers/zod'
import { Turnstile } from '@marsidev/react-turnstile'
import { ChevronRight } from 'lucide-react'
import { useEffect } from 'react'
import OTPInput from 'react-auth-code-input'
import { Controller, useForm } from 'react-hook-form'
Expand Down
118 changes: 68 additions & 50 deletions src/app/auth/phone/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import { useEffect } from 'react'

import logoDark from '@/assets/logo-dark.svg'
import logoLight from '@/assets/logo-light.svg'
import Card from '@/components/card/card'
import GithubLogo from '@/components/icons/github.logo.svg'
import DecorBlobs from '@/components/ui/decor-blobs/decor-blobs'
import Surface from '@/components/ui/surface/surface'
import { GithubClientID } from '@/constants/config'
import { useActionTrack, usePageTrack } from '@/hooks/tracke'
import { useTranslation } from '@/i18n/client'
Expand All @@ -34,58 +35,75 @@ function AuthPage(props: AuthPageProps) {
const onGithubClick = useActionTrack('login:github')

return (
<section className="anna-page-container flex h-screen items-center justify-center">
<Card className="with-slide-in">
<>
<div className="mb-4 flex flex-col items-center justify-center">
<Image
src={logoLight}
alt="clippingkk logo"
className="dark:hidden"
width={96}
height={96}
/>
<Image
src={logoDark}
alt="clippingkk logo"
className="hidden dark:block"
width={96}
height={96}
/>
</div>
<div className="flex w-full items-center justify-center rounded-sm">
<Link
href="/auth/phone"
className={
'flex bg-indigo-400 px-8 py-4 text-lg transition-colors duration-200 hover:bg-indigo-400'
}
>
{t('app.auth.phone')}
</Link>
<section className="anna-page-container relative flex min-h-screen items-center justify-center overflow-hidden px-4 py-10">
<DecorBlobs />
<Surface
variant="elevated"
className="with-slide-in relative z-10 w-full max-w-md p-8 md:p-10"
>
<div className="mb-6 flex flex-col items-center justify-center">
<Image
src={logoLight}
alt="clippingkk logo"
className="dark:hidden"
width={80}
height={80}
/>
<Image
src={logoDark}
alt="clippingkk logo"
className="hidden dark:block"
width={80}
height={80}
/>
<h1 className="font-lato mt-3 bg-gradient-to-r from-blue-400 via-blue-500 to-indigo-500 bg-clip-text text-2xl font-semibold tracking-tight text-transparent">
ClippingKK
</h1>
</div>

<nav
className="mb-6 grid grid-cols-2 gap-1 rounded-xl border border-slate-200/70 bg-slate-50/80 p-1 dark:border-slate-800/60 dark:bg-slate-900/60"
aria-label="Auth methods"
>
<Link
href="/auth/phone"
aria-current="page"
className="rounded-lg bg-blue-400 px-4 py-2 text-center text-sm font-medium text-white shadow-sm transition-colors hover:bg-blue-500 dark:bg-blue-400 dark:text-slate-950 dark:hover:bg-blue-300"
>
{t('app.auth.phone')}
</Link>
<Link
href="/auth/signin"
className="rounded-lg px-4 py-2 text-center text-sm font-medium text-slate-600 transition-colors hover:text-slate-900 dark:text-slate-300 dark:hover:text-white"
>
{t('app.auth.signin')}
</Link>
</nav>

<Link
href="/auth/signin"
className={
'flex px-8 py-4 text-lg transition-colors duration-200 hover:bg-indigo-400'
}
>
{t('app.auth.signin')}
</Link>
<div className="space-y-4">{children}</div>

<div className="relative my-6">
<div className="absolute inset-0 flex items-center">
<span className="w-full border-t border-slate-200/70 dark:border-slate-800/60" />
</div>
<hr className="my-2" />
{children}
<hr className="my-2" />
<div className="flex items-center justify-center">
<a
href={`https://github.com/login/oauth/authorize?client_id=${GithubClientID}&scope=user:email`}
onClick={onGithubClick}
title="github login"
>
<GithubLogo />
</a>
<div className="relative flex justify-center">
<span className="bg-white/70 px-3 text-xs tracking-wider text-slate-500 uppercase dark:bg-slate-900/70 dark:text-slate-400">
{t('app.auth.or') || 'or'}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Add missing app.auth.or locale entry

The new separator label uses t('app.auth.or') || 'or', but no app.auth.or key was added in locale files, so i18next will return the literal key string (truthy) and the 'or' fallback never applies. This makes auth pages render app.auth.or to end users (same pattern appears in src/app/auth/signin/layout.tsx), so please add the key in translations or pass a defaultValue to t(...) instead of relying on ||.

Useful? React with 👍 / 👎.

</span>
</div>
</>
</Card>
</div>

<div className="flex items-center justify-center">
<a
href={`https://github.com/login/oauth/authorize?client_id=${GithubClientID}&scope=user:email`}
onClick={onGithubClick}
title="github login"
className="rounded-xl p-2 transition-colors hover:bg-slate-100 dark:hover:bg-slate-800"
>
<GithubLogo />
</a>
</div>
</Surface>
</section>
Comment on lines +38 to 107
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

There is significant code duplication between src/app/auth/phone/layout.tsx and src/app/auth/signin/layout.tsx. Both layouts share the same structure, logo, title, navigation tabs, and social login section. Consider extracting this shared shell into a reusable component (e.g., AuthLayout) to improve maintainability and reduce duplication, which is one of the key goals of this PR.

)
}
Expand Down
105 changes: 61 additions & 44 deletions src/app/auth/signin/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import type React from 'react'

import logoDark from '@/assets/logo-dark.svg'
import logoLight from '@/assets/logo-light.svg'
import Card from '@/components/card/card'
import PageTrack from '@/components/track/page-track'
import DecorBlobs from '@/components/ui/decor-blobs/decor-blobs'
import Surface from '@/components/ui/surface/surface'
import { getTranslation } from '@/i18n'

import TrackedGithubLink from './tracked-github-link'
Expand All @@ -19,53 +20,69 @@ async function AuthPage(props: AuthPageProps) {
const { t } = await getTranslation()

return (
<section className="flex h-screen items-center justify-center bg-linear-to-br from-teal-100 to-green-300 dark:from-teal-900 dark:to-slate-900">
<section className="anna-page-container relative flex min-h-screen items-center justify-center overflow-hidden px-4 py-10">
<DecorBlobs />
<PageTrack page="auth" />
<Card className="with-slide-in container">
<>
<div className="mb-4 flex flex-col items-center justify-center">
<Image
src={logoLight}
alt="clippingkk logo"
className="dark:hidden"
width={96}
height={96}
/>
<Image
src={logoDark}
alt="clippingkk logo"
className="hidden dark:block"
width={96}
height={96}
/>
</div>
<div className="flex w-full items-center justify-center rounded-sm">
<Link
href="/auth/phone"
className={
'flex px-8 py-4 text-lg transition-colors duration-200 hover:bg-indigo-400'
}
>
{t('app.auth.phone')}
</Link>
<Surface
variant="elevated"
className="with-slide-in relative z-10 w-full max-w-md p-8 md:p-10"
>
<div className="mb-6 flex flex-col items-center justify-center">
<Image
src={logoLight}
alt="clippingkk logo"
className="dark:hidden"
width={80}
height={80}
/>
<Image
src={logoDark}
alt="clippingkk logo"
className="hidden dark:block"
width={80}
height={80}
/>
<h1 className="font-lato mt-3 bg-gradient-to-r from-blue-400 via-blue-500 to-indigo-500 bg-clip-text text-2xl font-semibold tracking-tight text-transparent">
ClippingKK
</h1>
</div>

<nav
className="mb-6 grid grid-cols-2 gap-1 rounded-xl border border-slate-200/70 bg-slate-50/80 p-1 dark:border-slate-800/60 dark:bg-slate-900/60"
aria-label="Auth methods"
>
<Link
href="/auth/phone"
className="rounded-lg px-4 py-2 text-center text-sm font-medium text-slate-600 transition-colors hover:text-slate-900 dark:text-slate-300 dark:hover:text-white"
>
{t('app.auth.phone')}
</Link>
<Link
href="/auth/signin"
aria-current="page"
className="rounded-lg bg-blue-400 px-4 py-2 text-center text-sm font-medium text-white shadow-sm transition-colors hover:bg-blue-500 dark:bg-blue-400 dark:text-slate-950 dark:hover:bg-blue-300"
>
{t('app.auth.signin')}
</Link>
</nav>

<Link
href="/auth/signin"
className={
'flex bg-indigo-400 px-8 py-4 text-lg transition-colors duration-200 hover:bg-indigo-400'
}
>
{t('app.auth.signin')}
</Link>
<div className="space-y-4">{children}</div>

<div className="relative my-6">
<div className="absolute inset-0 flex items-center">
<span className="w-full border-t border-slate-200/70 dark:border-slate-800/60" />
</div>
<hr className="my-2" />
{children}
<hr className="my-2" />
<div className="flex items-center justify-center">
<TrackedGithubLink />
<div className="relative flex justify-center">
<span className="bg-white/70 px-3 text-xs tracking-wider text-slate-500 uppercase dark:bg-slate-900/70 dark:text-slate-400">
{t('app.auth.or') || 'or'}
</span>
</div>
</>
</Card>
</div>

<div className="flex items-center justify-center">
<TrackedGithubLink />
</div>
</Surface>
</section>
)
}
Expand Down
36 changes: 19 additions & 17 deletions src/app/dash/[userid]/admin/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,38 +52,40 @@ async function AdminPanel(props: PageProps) {
})

return (
<div className="container mx-auto px-4 py-8">
<div className="mx-auto max-w-6xl overflow-hidden rounded-xl border border-gray-200 bg-white shadow-lg dark:border-gray-700 dark:bg-gray-900">
<div className="bg-gradient-to-br from-blue-400 to-indigo-500 px-8 py-8 dark:from-blue-500 dark:to-indigo-600">
<section className="with-slide-in w-full">
<div className="overflow-hidden rounded-2xl border border-white/40 bg-white/70 shadow-sm backdrop-blur-xl dark:border-slate-800/40 dark:bg-slate-900/70">
<div className="bg-gradient-to-br from-blue-400 via-blue-500 to-indigo-500 px-8 py-8">
<div className="flex items-center justify-center gap-4 text-white">
<div className="rounded-lg bg-white/10 p-2 backdrop-blur-sm">
<BookOpenCheck className="h-8 w-8" />
<div className="rounded-xl bg-white/15 p-2 ring-1 ring-white/20 backdrop-blur-sm">
<BookOpenCheck className="h-7 w-7" />
</div>
<div className="text-center">
<h1 className="text-3xl font-bold">{t('Homeless Books')}</h1>
<p className="mt-1 text-sm text-blue-100 dark:text-blue-200">
<h1 className="text-3xl font-semibold tracking-tight">
{t('Homeless Books')}
</h1>
<p className="mt-1 text-sm text-blue-50">
{t('Manage and sync unprocessed book entries')}
</p>
</div>
</div>
</div>

<div className="p-8">
<div className="mb-8 flex flex-wrap items-center justify-between gap-4">
<div className="p-6 md:p-8">
<div className="mb-6 flex flex-wrap items-center justify-between gap-4">
<div className="flex items-center gap-2">
<div className="h-2 w-2 rounded-full bg-blue-400"></div>
<span className="text-sm font-medium text-gray-600 dark:text-gray-300">
<div className="h-2 w-2 rounded-full bg-blue-400" />
<span className="text-sm font-medium text-slate-600 dark:text-slate-300">
{t('Showing books')} {offset + 1} -{' '}
{offset + (data!.adminDashboard.uncheckedBooks?.length || 0)}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The non-null assertion (!) on data is unsafe. If the query returns no data or fails silently, this will cause a runtime error. It's better to use optional chaining with a fallback value to ensure the page doesn't crash.

Suggested change
{offset + (data!.adminDashboard.uncheckedBooks?.length || 0)}
{offset + (data?.adminDashboard?.uncheckedBooks?.length || 0)}

</span>
</div>
<div className="flex gap-3">
<Link
href={`/dash/${uid}/admin?offset=${Math.max(0, offset - 50)}`}
className={`flex items-center gap-2 rounded-lg border px-4 py-2.5 text-sm font-medium transition-all duration-200 ${
className={`inline-flex items-center gap-2 rounded-xl border px-4 py-2 text-sm font-medium transition-colors duration-200 ${
offset <= 0
? 'cursor-not-allowed border-gray-200 text-gray-400 opacity-50 dark:border-gray-700 dark:text-gray-500'
: 'border-gray-300 text-gray-700 hover:border-gray-400 hover:bg-gray-50 dark:border-gray-600 dark:text-gray-200 dark:hover:border-gray-500 dark:hover:bg-gray-800'
? 'cursor-not-allowed border-slate-200 text-slate-400 opacity-50 dark:border-slate-700 dark:text-slate-500'
: 'border-slate-200 text-slate-700 hover:border-blue-400/60 hover:bg-blue-400/5 dark:border-slate-700 dark:text-slate-200 dark:hover:border-blue-400/60 dark:hover:bg-blue-400/10'
}`}
aria-disabled={offset <= 0}
>
Expand All @@ -92,7 +94,7 @@ async function AdminPanel(props: PageProps) {
</Link>
<Link
href={`/dash/${uid}/admin?offset=${offset + 50}`}
className="flex items-center gap-2 rounded-lg bg-blue-400 px-4 py-2.5 text-sm font-medium text-white shadow-sm transition-all duration-200 hover:bg-blue-500 dark:bg-blue-400 dark:hover:bg-blue-500"
className="inline-flex items-center gap-2 rounded-xl bg-blue-400 px-4 py-2 text-sm font-medium text-white shadow-sm transition-all duration-200 hover:-translate-y-0.5 hover:bg-blue-500 hover:shadow-md dark:text-slate-950 dark:hover:bg-blue-300"
>
{t('Next')}
<ArrowRightCircle className="h-4 w-4" />
Expand All @@ -107,15 +109,15 @@ async function AdminPanel(props: PageProps) {
<div className="mt-8 flex justify-center">
<Link
href={`/dash/${uid}/admin?offset=${offset + 50}`}
className="flex items-center gap-2 rounded-lg bg-gradient-to-r from-blue-400 to-blue-500 px-6 py-3 font-medium text-white shadow-sm transition-all duration-200 hover:from-blue-500 hover:to-blue-600 hover:shadow-md dark:from-blue-400 dark:to-blue-500 dark:hover:from-blue-500 dark:hover:to-blue-600"
className="inline-flex items-center gap-2 rounded-xl bg-blue-400 px-6 py-3 font-medium text-white shadow-sm transition-all duration-200 hover:-translate-y-0.5 hover:bg-blue-500 hover:shadow-md dark:text-slate-950 dark:hover:bg-blue-300"
>
{t('Load More Books')}
<ArrowRightCircle className="h-5 w-5" />
</Link>
</div>
</div>
</div>
</div>
</section>
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import Image from 'next/image'
import Link from 'next/link'

import { checkIsPremium } from '@/compute/user'
import ElegantDivider from '@/components/divider/elegant-divider'
import ClippingRichContent from '@/components/text-content/clipping-rich-content'
import { checkIsPremium } from '@/compute/user'
import { getTranslation } from '@/i18n'
import { isGrandAdmin } from '@/services/admin'
import { resolveMediaUrl } from '@/utils/image'
Expand Down
12 changes: 6 additions & 6 deletions src/app/dash/[userid]/clippings/[clippingid]/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,18 @@ function Layout(props: Props) {
</svg>
</div>

{/* Main card with gradient background */}
<div className="relative border border-gray-200/60 bg-gradient-to-br from-white/95 via-gray-50/90 to-blue-50/50 shadow-xl backdrop-blur-md dark:border-zinc-800/50 dark:from-zinc-900/95 dark:via-zinc-900/90 dark:to-blue-950/30">
{/* Additional gradient overlay for depth */}
<div className="pointer-events-none absolute inset-0 bg-gradient-to-t from-transparent via-transparent to-blue-400/[0.015] dark:to-blue-400/[0.025]" />
{/* Main card with unified glass background */}
<div className="relative rounded-3xl border border-white/40 bg-white/70 shadow-sm backdrop-blur-xl dark:border-slate-800/40 dark:bg-slate-900/70">
{/* Subtle blue depth overlay */}
<div className="pointer-events-none absolute inset-0 rounded-3xl bg-gradient-to-t from-transparent via-transparent to-blue-400/[0.02] dark:to-blue-400/[0.04]" />

{/* Content wrapper with responsive grid */}
<div className="relative z-10 grid grid-cols-1 divide-y divide-gray-200/50 lg:grid-cols-[1fr,380px] lg:divide-x lg:divide-y-0 dark:divide-zinc-800/40">
<div className="relative z-10 grid grid-cols-1 divide-y divide-slate-200/50 lg:grid-cols-[1fr,380px] lg:divide-x lg:divide-y-0 dark:divide-slate-800/50">
{/* Main content area */}
<div className="p-6 lg:p-10">{content}</div>

{/* Sidebar area */}
<div className="bg-gradient-to-b from-transparent to-gray-50/50 p-6 lg:p-8 dark:to-zinc-800/30">
<div className="bg-gradient-to-b from-transparent to-blue-50/40 p-6 lg:p-8 dark:to-blue-950/20">
{sidebar}
</div>
</div>
Expand Down
3 changes: 1 addition & 2 deletions src/app/dash/[userid]/comments/loading.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { cn } from '@/lib/utils'

import { glassCardClass } from '@/components/card/glass-card'
import { cn } from '@/lib/utils'

export default function CommentsLoading() {
return (
Expand Down
Loading
Loading