feat: add footer
This commit is contained in:
+4
-1
@@ -1,3 +1,6 @@
|
|||||||
{
|
{
|
||||||
"extends": "next/core-web-vitals"
|
"extends": "next/core-web-vitals",
|
||||||
|
"rules": {
|
||||||
|
"no-console": "warn"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -28,7 +28,7 @@ async function validateRequest(
|
|||||||
try {
|
try {
|
||||||
evt = wh.verify(payloadString, svixHeaders) as Event;
|
evt = wh.verify(payloadString, svixHeaders) as Event;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.error(error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,7 +67,7 @@ const handleClerkWebhook = httpAction(async (ctx, request) => {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
console.log('ignored Clerk webhook event', event.type);
|
console.warn('ignored Clerk webhook event', event.type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new Response(null, {
|
return new Response(null, {
|
||||||
|
|||||||
+6
-2
@@ -1,3 +1,4 @@
|
|||||||
|
import Footer from '@/components/Footer';
|
||||||
import Navbar from '@/components/Navbar';
|
import Navbar from '@/components/Navbar';
|
||||||
import { ConvexProvider, NextThemesProvider } from '@/providers';
|
import { ConvexProvider, NextThemesProvider } from '@/providers';
|
||||||
import { ClerkProvider } from '@clerk/nextjs';
|
import { ClerkProvider } from '@clerk/nextjs';
|
||||||
@@ -24,7 +25,7 @@ export default function RootLayout({
|
|||||||
suppressHydrationWarning
|
suppressHydrationWarning
|
||||||
>
|
>
|
||||||
<body
|
<body
|
||||||
className={`w-full h-full flex flex-col bg-white text-primary-gray dark:bg-primary-gray dark:text-white ${inter.className}`}
|
className={`w-full h-full flex flex-col bg-white text-primary-gray dark:bg-primary-gray dark:text-white ${inter.className} overflow-auto`}
|
||||||
>
|
>
|
||||||
<ClerkProvider
|
<ClerkProvider
|
||||||
publishableKey={process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY}
|
publishableKey={process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY}
|
||||||
@@ -36,7 +37,10 @@ export default function RootLayout({
|
|||||||
showSpinner={false}
|
showSpinner={false}
|
||||||
/>
|
/>
|
||||||
<Navbar />
|
<Navbar />
|
||||||
<div className='p-4 w-full h-full flex flex-col'>{children}</div>
|
<div className='p-4 w-full h-full flex flex-col'>
|
||||||
|
{children}
|
||||||
|
<Footer />
|
||||||
|
</div>
|
||||||
</NextThemesProvider>
|
</NextThemesProvider>
|
||||||
</ConvexProvider>
|
</ConvexProvider>
|
||||||
</ClerkProvider>
|
</ClerkProvider>
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
export default function PostPage({ params }: { params: { id: string } }) {}
|
||||||
@@ -19,7 +19,7 @@ export default async function UserProfilePage({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main className='flex flex-col w-full h-full items-center'>
|
<main className='flex flex-col flex-1 w-full items-center'>
|
||||||
<div className='w-full max-w-4xl'>
|
<div className='w-full max-w-4xl'>
|
||||||
<UserProfile user={user} />
|
<UserProfile user={user} />
|
||||||
<UserPosts user={user} />
|
<UserPosts user={user} />
|
||||||
|
|||||||
@@ -95,20 +95,16 @@ export default function Editor({ post }: { post?: Doc<'posts'> }) {
|
|||||||
</div>
|
</div>
|
||||||
<div></div>
|
<div></div>
|
||||||
</div>
|
</div>
|
||||||
<div className='flex flex-col p-4 h-0 flex-grow'>
|
<div className='flex flex-col p-4 h-0 flex-grow overflow-auto'>
|
||||||
<div
|
<div
|
||||||
className={`${mode === 'write' ? '' : 'hidden'} flex-1 overflow-auto`}
|
className={`${mode === 'write' ? '' : 'hidden'} flex-1 overflow-auto`}
|
||||||
ref={editorRef}
|
ref={editorRef}
|
||||||
></div>
|
></div>
|
||||||
<div
|
<div className={`${mode === 'preview' ? '' : 'hidden'} flex-1`}>
|
||||||
className={`${
|
|
||||||
mode === 'preview' ? '' : 'hidden'
|
|
||||||
} flex-1 overflow-auto`}
|
|
||||||
>
|
|
||||||
<PostContent content={Text.of(currentDoc).toString()} />
|
<PostContent content={Text.of(currentDoc).toString()} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className='flex items-center justify-end p-4 pt-0 gap-4'>
|
<div className='flex items-center justify-end p-4 gap-4'>
|
||||||
<button
|
<button
|
||||||
onClick={() => router.back()}
|
onClick={() => router.back()}
|
||||||
type='button'
|
type='button'
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
import Link from 'next/link';
|
||||||
|
|
||||||
|
export default function Footer() {
|
||||||
|
return (
|
||||||
|
<div className='flex flex-col w-full items-center justify-center px-4 mt-4'>
|
||||||
|
<footer className='flex flex-col items-center justify-between gap-2 w-full max-w-4xl text-sm text-primary-white border-t border-gray-600 py-4'>
|
||||||
|
<div className='flex items-center justify-center w-full flex-wrap gap-4'>
|
||||||
|
<Link
|
||||||
|
href='/about'
|
||||||
|
className='hover:text-primary-orange'
|
||||||
|
>
|
||||||
|
About
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
href='/contact'
|
||||||
|
className='hover:text-primary-orange'
|
||||||
|
>
|
||||||
|
Contact
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
href='/terms'
|
||||||
|
className='hover:text-primary-orange'
|
||||||
|
>
|
||||||
|
Terms
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
href='/privacy'
|
||||||
|
className='hover:text-primary-orange'
|
||||||
|
>
|
||||||
|
Privacy
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
href='https://github.com/StevanFreeborn/conve-x'
|
||||||
|
className='hover:text-primary-orange'
|
||||||
|
>
|
||||||
|
Code
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span className='self-center whitespace-nowrap italic'>
|
||||||
|
conve<span className='font-bold text-primary-accent'>X</span>
|
||||||
|
</span>
|
||||||
|
<span> © 2023</span>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -90,7 +90,12 @@ export default function Post({ post }: { post: PostWithUserDto }) {
|
|||||||
>
|
>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<Link href={`/posts/${post._id}/edit`}>Edit post</Link>
|
<Link
|
||||||
|
onClick={() => setModalOpen(false)}
|
||||||
|
href={`/posts/${post._id}/edit`}
|
||||||
|
>
|
||||||
|
Edit post
|
||||||
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
<li className='text-red-600'>
|
<li className='text-red-600'>
|
||||||
<button
|
<button
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import Post from './Post';
|
|||||||
import SpinningLoader from './SpinningLoader';
|
import SpinningLoader from './SpinningLoader';
|
||||||
|
|
||||||
export default function UserPosts({ user }: { user: UserDto }) {
|
export default function UserPosts({ user }: { user: UserDto }) {
|
||||||
const PAGE_SIZE = 1;
|
const PAGE_SIZE = 2;
|
||||||
const pager = usePaginatedQuery(
|
const pager = usePaginatedQuery(
|
||||||
api.posts.getUsersPostById,
|
api.posts.getUsersPostById,
|
||||||
{
|
{
|
||||||
@@ -19,8 +19,6 @@ export default function UserPosts({ user }: { user: UserDto }) {
|
|||||||
|
|
||||||
const postsWithUser = pager.results.map(post => ({ ...post, user }));
|
const postsWithUser = pager.results.map(post => ({ ...post, user }));
|
||||||
|
|
||||||
console.log(postsWithUser);
|
|
||||||
|
|
||||||
if (pager.isLoading === false && postsWithUser.length == 0) {
|
if (pager.isLoading === false && postsWithUser.length == 0) {
|
||||||
return (
|
return (
|
||||||
<div className='flex flex-col items-center justify-center border-t border-gray-600 w-full h-full'>
|
<div className='flex flex-col items-center justify-center border-t border-gray-600 w-full h-full'>
|
||||||
@@ -57,9 +55,9 @@ export default function UserPosts({ user }: { user: UserDto }) {
|
|||||||
Loading...
|
Loading...
|
||||||
</div>
|
</div>
|
||||||
) : pager.status === 'CanLoadMore' ? (
|
) : pager.status === 'CanLoadMore' ? (
|
||||||
<div className='flex items-center p-5'>
|
<div className='flex items-center p-5 pb-1'>
|
||||||
<button
|
<button
|
||||||
className='bg-primary-accent px-3 py-1 rounded-full'
|
className='bg-primary-accent text-white px-3 py-1 rounded-full'
|
||||||
onClick={() => pager.loadMore(PAGE_SIZE)}
|
onClick={() => pager.loadMore(PAGE_SIZE)}
|
||||||
disabled={pager.status !== 'CanLoadMore'}
|
disabled={pager.status !== 'CanLoadMore'}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ const basicDarkTheme = EditorView.theme(
|
|||||||
color: base01,
|
color: base01,
|
||||||
backgroundColor: background,
|
backgroundColor: background,
|
||||||
borderRadius: '0.375rem',
|
borderRadius: '0.375rem',
|
||||||
padding: '0.5rem 0',
|
|
||||||
},
|
},
|
||||||
'.cm-gutter': {
|
'.cm-gutter': {
|
||||||
height: '100%',
|
height: '100%',
|
||||||
|
|||||||
Reference in New Issue
Block a user