mirror of
https://github.com/ahmadk953/tasko.git
synced 2025-01-30 16:43:37 +00:00
Added Blog Page and Housekeeping
This commit is contained in:
parent
db4bf103c3
commit
d32415232e
18 changed files with 6860 additions and 769 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -36,3 +36,4 @@ next-env.d.ts
|
|||
|
||||
# other
|
||||
/.vscode/
|
||||
/.content-collections
|
||||
|
|
|
@ -42,3 +42,4 @@ next-env.d.ts
|
|||
package.json
|
||||
yarn.lock
|
||||
README.md
|
||||
/.content-collections
|
||||
|
|
32
README.md
32
README.md
|
@ -5,11 +5,14 @@
|
|||
|
||||
## About
|
||||
|
||||
Tasko is a company that helps you manage your tasks efficiently by using kanban boards. Kanban boards are a visual way of organizing your work into different stages, such as to-do, in progress, and done. With Tasko, you can create and customize your own kanban boards, add tasks, and collaborate with your team members. Tasko is designed to be simple, intuitive, and flexible, so you can focus on getting things done and achieving your goals.
|
||||
Tasko is a website that helps you manage your tasks efficiently by using kanban boards. Kanban boards are a visual way of organizing your work into different stages, such as to-do, in progress, and done. With Tasko, you can create and customize your own kanban boards and add tasks. Tasko is designed to be simple, intuitive, and flexible, so you can focus on getting things done and achieving your goals. [Try Tasko Today!](https://tasko-omega.vercel.app/)
|
||||
|
||||
## Documentation
|
||||
|
||||
Currently, there is no documentation or wiki available but there will be one added in the future.
|
||||
> [!WARNING]
|
||||
> Documentation is not complete and is still a work in progress.
|
||||
|
||||
Documentation can be found on our new, [Mintlify page](https://tasko.mintlify.app/).
|
||||
|
||||
## Roadmap
|
||||
|
||||
|
@ -22,11 +25,30 @@ This will be published on the site some time soon but for now, the roadmap will
|
|||
- [ ] Add end-to-end Database encryption (for customer data such as card titles and descriptions, and subscription information)
|
||||
- [ ] Add dark mode
|
||||
- [ ] Markdown Support in Card Descriptions
|
||||
- [ ] Self-Hosted Version
|
||||
|
||||
## Contributing and Development
|
||||
|
||||
### Development Commands
|
||||
|
||||
Start Dev Server: ``yarn dev``
|
||||
|
||||
Production Build: ``yarn build``
|
||||
|
||||
Start Production Server: ``yarn start``
|
||||
|
||||
Linting: ``yarn lint``
|
||||
|
||||
Check Formatting: ``yarn format``
|
||||
|
||||
Fix Formatting: ``yarn format:fix``
|
||||
|
||||
Please make sure to lint and check formatting (using the commands listed above) before submitting a Pull Request.
|
||||
|
||||
## Legal
|
||||
|
||||
[Privacy Policy](https://tasko-omega.vercel.app/privacy-policy)
|
||||
[Privacy Policy](https://tasko-omega.vercel.app/privacy-policy) _Temporarily removed to revamp it._
|
||||
|
||||
[Terms of Service](https://tasko-omega.vercel.app/terms-of-service) _The Terms of Service will be added once a CMS is added and implemented._
|
||||
[Terms of Service](https://tasko-omega.vercel.app/terms-of-service) _The Terms of Service will be added soon!_
|
||||
|
||||
[License](https://github.com/ahmadk953/tasko/blob/main/LICENCE)
|
||||
[License](https://github.com/ahmadk953/tasko/blob/main/LICENCE) _Will be located on website at some point in time._
|
||||
|
|
|
@ -8,11 +8,11 @@ export const Footer = () => {
|
|||
<div className='mx-auto flex w-full items-center justify-between md:max-w-screen-2xl'>
|
||||
<Logo />
|
||||
<div className='flex w-full items-center justify-between space-x-4 md:block md:w-auto'>
|
||||
<Button size='sm' variant='ghost'>
|
||||
<Link href='/privacy-policy'>Privacy Policy</Link>
|
||||
<Button className='italic' size='sm' variant='ghost'>
|
||||
Privacy Policy - Temporarily Removed
|
||||
</Button>
|
||||
<Button size='sm' variant='ghost'>
|
||||
Terms of Service
|
||||
<Button className='italic' size='sm' variant='ghost'>
|
||||
Terms of Service - Coming Soon
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
|
@ -13,14 +13,22 @@ export const Navbar = async () => {
|
|||
<div className='fixed top-0 flex h-14 w-full items-center border-b bg-white px-4 shadow-sm'>
|
||||
<div className='mx-auto flex w-full items-center justify-between md:max-w-screen-2xl'>
|
||||
<Logo />
|
||||
<div className='ml-0 flex w-full flex-auto items-center space-x-1 md:ml-6 md:block md:w-auto md:space-x-4'>
|
||||
<Button size='sm' variant='ghost' asChild>
|
||||
<Link href='/blog'>Blog</Link>
|
||||
</Button>
|
||||
<Button size='sm' variant='ghost' asChild>
|
||||
<Link href='https://tasko.mintlify.app/'>Docs</Link>
|
||||
</Button>
|
||||
</div>
|
||||
<div className='flex w-full items-center justify-between space-x-4 md:block md:w-auto'>
|
||||
{!isSignedIn ? (
|
||||
<div className='flex w-full justify-between space-x-4 md:block md:w-auto'>
|
||||
<Button size='sm' variant='outline' asChild>
|
||||
<Link href='sign-in'>Login</Link>
|
||||
<Link href='/sign-in'>Login</Link>
|
||||
</Button>
|
||||
<Button size='sm' asChild>
|
||||
<Link href='sign-up'>Get Tasko for Free</Link>
|
||||
<Link href='/sign-up'>Get Tasko for Free</Link>
|
||||
</Button>
|
||||
</div>
|
||||
) : (
|
32
app/(main)/blog/page.tsx
Normal file
32
app/(main)/blog/page.tsx
Normal file
|
@ -0,0 +1,32 @@
|
|||
import { allBlogPosts } from 'content-collections';
|
||||
import Image from 'next/image';
|
||||
import Link from 'next/link';
|
||||
|
||||
const BlogPage = () => {
|
||||
return (
|
||||
<div className='ml-4 mr-4 flex flex-col items-center space-y-10'>
|
||||
<h1 className='text-4xl font-semibold text-neutral-700'>Blog</h1>
|
||||
<div className='grid grid-cols-2 gap-20 sm:grid-cols-3 lg:grid-cols-4'>
|
||||
{allBlogPosts.map((post) => (
|
||||
<div className='space-y-4 text-center' key={post._meta.path}>
|
||||
<Link href={`blog/posts/${post._meta.path}`}>
|
||||
<Image
|
||||
src={post.coverImage}
|
||||
height={100}
|
||||
width={300}
|
||||
alt='post cover image'
|
||||
className='aspect-video w-full rounded-md object-cover'
|
||||
/>
|
||||
<h2 className='text-lg font-semibold text-neutral-700'>
|
||||
{post.title}
|
||||
</h2>
|
||||
<p className='text-sm text-neutral-500'>{post.summary}</p>
|
||||
</Link>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default BlogPage;
|
40
app/(main)/blog/posts/[post]/page.tsx
Normal file
40
app/(main)/blog/posts/[post]/page.tsx
Normal file
|
@ -0,0 +1,40 @@
|
|||
import { MDXContent } from '@content-collections/mdx/react';
|
||||
import { allBlogPosts } from 'content-collections';
|
||||
import Image from 'next/image';
|
||||
|
||||
interface PostPageProps {
|
||||
params: Promise<{ post: string }>;
|
||||
}
|
||||
|
||||
const PostPage = async (props: PostPageProps) => {
|
||||
const params = await props.params;
|
||||
const post = allBlogPosts.find((post) => post._meta.path === params.post);
|
||||
|
||||
if (!post) {
|
||||
return (
|
||||
<h1 className='text-6xl font-semibold text-neutral-900'>
|
||||
Post not found
|
||||
</h1>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='mx-auto p-4 md:p-6 lg:p-8'>
|
||||
<Image
|
||||
className='mb-2 h-64 w-full rounded-md object-cover md:h-[500px]'
|
||||
src={post.coverImage}
|
||||
width={1200}
|
||||
height={600}
|
||||
alt='post cover image'
|
||||
/>
|
||||
<h1 className='mb-12 text-center text-6xl font-bold text-neutral-900'>
|
||||
{post.title}
|
||||
</h1>{' '}
|
||||
<div className='container prose prose-headings:mt-8 prose-headings:font-semibold prose-headings:text-black prose-h1:text-5xl prose-h2:text-4xl prose-h3:text-3xl prose-h4:text-2xl prose-h5:text-xl prose-h6:text-lg prose-p:text-xl dark:prose-headings:text-white'>
|
||||
<MDXContent code={post.mdx} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default PostPage;
|
14
app/(main)/blog/posts/blog-welcome.mdx
Normal file
14
app/(main)/blog/posts/blog-welcome.mdx
Normal file
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
title: 'Welcome to the Blog!'
|
||||
summary: 'Welcome to our new blog page!'
|
||||
coverImage: '/hero.svg'
|
||||
datePublished: ''
|
||||
---
|
||||
|
||||
## Welcome!
|
||||
|
||||
Hello and welcome to our new blog page! We are so exited to finally have a place to share updates and news about our app.
|
||||
|
||||
## What's next?
|
||||
|
||||
As you can see, although we have a blog page, it's a bit basic at the moment. In the future, we are planning to add things such as tags and dates as well as other stuff. In terms of the website it's self, we have a few major feates that we plan to add in the comming months.
|
|
@ -1,282 +0,0 @@
|
|||
import Link from 'next/link';
|
||||
|
||||
const PrivacyPolicyPage = () => {
|
||||
return (
|
||||
<div className='ml-10 mr-10 content-center text-center'>
|
||||
<h1 className='pb-10 text-4xl font-bold text-slate-800'>
|
||||
TASKO PRIVACY POLICY
|
||||
</h1>
|
||||
|
||||
<div>
|
||||
<h1 className='text-md font-semibold text-slate-800'>
|
||||
TASKO (the “Company”) is committed to maintaining robust privacy
|
||||
protections for its users. Our Privacy Policy (“Privacy Policy”) is
|
||||
designed to help you understand how we collect, use and safeguard the
|
||||
information you provide to us and to assist you in making informed
|
||||
decisions when using our Service.
|
||||
</h1>
|
||||
<br />
|
||||
<p className='text-md font-medium text-slate-700'>
|
||||
For purposes of this Agreement, “Site” refers to the Company’s
|
||||
website, which can be accessed at{' '}
|
||||
<Link
|
||||
href='https://tasko-omega.vercel.app'
|
||||
className='text-blue-600/100 underline'
|
||||
>
|
||||
https://tasko-omega.vercel.app
|
||||
</Link>
|
||||
. “Service” refers to the Company’s services accessed via the Site, in
|
||||
which users can create Kanban Boards with lists and cards. The terms
|
||||
“we,” “us,” and “our” refer to the Company. “You” refers to you, as a
|
||||
user of our Site or our Service. By accessing our Site or our Service,
|
||||
you accept our Privacy Policy and Terms of Use (found here:{' '}
|
||||
<Link
|
||||
href='https://tasko-omega.vercel.app/terms-of-service'
|
||||
className='text-blue-600/100 underline'
|
||||
>
|
||||
https://tasko-omega.vercel.app/terms-of-service
|
||||
</Link>
|
||||
), and you consent to our collection, storage, use and disclosure of
|
||||
your Personal Information as described in this Privacy Policy.
|
||||
</p>
|
||||
<br />
|
||||
<h1 className='text-xl font-semibold text-slate-800'>
|
||||
I. INFORMATION WE COLLECT
|
||||
</h1>
|
||||
<br />
|
||||
<p className='text-md font-medium text-slate-700'>
|
||||
We collect “Non-Personal Information” and “Personal Information.”
|
||||
Non-Personal Information includes information that cannot be used to
|
||||
personally identify you, such as anonymous usage data, general
|
||||
demographic information we may collect, referring/exit pages and URLs,
|
||||
platform types, preferences you submit and preferences that are
|
||||
generated based on the data you submit and number of clicks. Personal
|
||||
Information includes your email and full name (first and last), which
|
||||
you submit to us through the registration process at the Site. We may
|
||||
also collect your payment information, billing address, and phone
|
||||
number in addition if you choose to purchase a paid plan through our
|
||||
payment processor, Stripe.
|
||||
</p>
|
||||
<br />
|
||||
<h1 className='text-1xl font-semibold text-slate-800'>
|
||||
1. Information collected via Technology
|
||||
</h1>
|
||||
<br />
|
||||
<p className='text-md font-medium text-slate-700'>
|
||||
To activate the Service you do not need to submit any Personal
|
||||
Information other than your email address and full name (first and
|
||||
last). To use the Service thereafter, you do not need to submit
|
||||
further Personal Information unless you are purchasing a paid plan.
|
||||
However, in an effort to improve the quality of the Service, we track
|
||||
information provided to us by your browser or by our software
|
||||
application when you view or use the Service, such as the website you
|
||||
came from (known as the “referring URL”), the type of browser you use,
|
||||
the device from which you connected to the Service, the time and date
|
||||
of access, and other information that does not personally identify
|
||||
you. We track this information using cookies, or small text files
|
||||
which include an anonymous unique identifier. Cookies are sent to a
|
||||
user’s browser from our servers and are stored on the user’s computer
|
||||
hard drive. Sending a cookie to a user’s browser enables us to collect
|
||||
Non-Personal information about that user and keep a record of the
|
||||
user’s preferences when utilizing our services, both on an individual
|
||||
and aggregate basis. For example, the Company may use cookies to
|
||||
collect the following information:
|
||||
<ul className='pb-2 pt-2'>
|
||||
<li>- What user agent (browser) you are using</li>
|
||||
<li>- What device you are currently using</li>
|
||||
</ul>
|
||||
The Company may use both persistent and session cookies; persistent
|
||||
cookies remain on your computer after you close your session and until
|
||||
you delete them, while session cookies expire when you close your
|
||||
browser.
|
||||
</p>
|
||||
<br />
|
||||
<h1 className='text-1xl font-semibold text-slate-800'>
|
||||
2. Information you provide us by registering for an account
|
||||
</h1>
|
||||
<br />
|
||||
<p className='text-md font-medium text-slate-700'>
|
||||
In addition to the information provided automatically by your browser
|
||||
when you visit the Site, to become a subscriber to the Service you
|
||||
will need to create a personal profile. You can create a profile by
|
||||
registering with the Service and entering your email address, and
|
||||
creating a user name and a password. By registering, you are
|
||||
authorizing us to collect, store and use your email address in
|
||||
accordance with this Privacy Policy.
|
||||
</p>
|
||||
<br />
|
||||
<h1 className='text-1xl font-semibold text-slate-800'>
|
||||
3. Children’s Privacy
|
||||
</h1>
|
||||
<br />
|
||||
<p className='text-md font-medium text-slate-700'>
|
||||
The Site and the Service are not directed to anyone under the age of
|
||||
13. The Site does not knowingly collect or solicit information from
|
||||
anyone under the age of 13, or allow anyone under the age of 13 to
|
||||
sign up for the Service. In the event that we learn that we have
|
||||
gathered personal information from anyone under the age of 13 without
|
||||
the consent of a parent or guardian, we will delete that information
|
||||
as soon as possible. If you believe we have collected such
|
||||
information, please contact us at{' '}
|
||||
<Link
|
||||
href='mailto:ahmad.khan@outoforgedu.onmicrosoft.com'
|
||||
className='text-blue-600/100 underline'
|
||||
>
|
||||
ahmad.khan@outoforgedu.onmicrosoft.com
|
||||
</Link>
|
||||
.
|
||||
</p>
|
||||
<br />
|
||||
<h1 className='text-xl font-semibold text-slate-800'>
|
||||
II. HOW WE USE AND SHARE INFORMATION
|
||||
</h1>
|
||||
<br />
|
||||
<h1 className='text-1xl font-semibold text-slate-800'>
|
||||
Personal Information:
|
||||
</h1>
|
||||
<br />
|
||||
<p className='text-md font-medium text-slate-700'>
|
||||
Except as otherwise stated in this Privacy Policy, we do not sell,
|
||||
trade, rent or otherwise share for marketing purposes your Personal
|
||||
Information with third parties without your consent. We do share
|
||||
Personal Information with vendors who are performing services for the
|
||||
Company, such as the servers for our email communications who are
|
||||
provided access to user’s email address for purposes of sending emails
|
||||
from us. Those vendors use your Personal Information only at our
|
||||
direction and in accordance with our Privacy Policy. In general, the
|
||||
Personal Information you provide to us is used to help us communicate
|
||||
with you. For example, we use Personal Information to contact users in
|
||||
response to questions, solicit feedback from users, provide technical
|
||||
support, and inform users about promotional offers. We may share
|
||||
Personal Information with outside parties if we have a good-faith
|
||||
belief that access, use, preservation or disclosure of the information
|
||||
is reasonably necessary to meet any applicable legal process or
|
||||
enforceable governmental request; to enforce applicable Terms of
|
||||
Service, including investigation of potential violations; address
|
||||
fraud, security or technical concerns; or to protect against harm to
|
||||
the rights, property, or safety of our users or the public as required
|
||||
or permitted by law.
|
||||
</p>
|
||||
<br />
|
||||
<h1 className='text-1xl font-semibold text-slate-800'>
|
||||
Non-Personal Information:
|
||||
</h1>
|
||||
<br />
|
||||
<p className='text-md font-medium text-slate-700'>
|
||||
In general, we use Non-Personal Information to help us improve the
|
||||
Service and customize the user experience. We also aggregate
|
||||
Non-Personal Information in order to track trends and analyze use
|
||||
patterns on the Site. This Privacy Policy does not limit in any way
|
||||
our use or disclosure of Non-Personal Information and we reserve the
|
||||
right to use and disclose such Non-Personal Information to our
|
||||
partners, advertisers and other third parties at our discretion. In
|
||||
the event we undergo a business transaction such as a merger,
|
||||
acquisition by another company, or sale of all or a portion of our
|
||||
assets, your Personal Information may be among the assets transferred.
|
||||
You acknowledge and consent that such transfers may occur and are
|
||||
permitted by this Privacy Policy, and that any acquirer of our assets
|
||||
may continue to process your Personal Information as set forth in this
|
||||
Privacy Policy. If our information practices change at any time in the
|
||||
future, we will post the policy changes to the Site so that you may
|
||||
opt out of the new information practices. We suggest that you check
|
||||
the Site periodically if you are concerned about how your information
|
||||
is used.
|
||||
</p>
|
||||
<br />
|
||||
<h1 className='text-xl font-semibold text-slate-800'>
|
||||
III. HOW WE PROTECT INFORMATION
|
||||
</h1>
|
||||
<br />
|
||||
<p className='text-md font-medium text-slate-700'>
|
||||
We implement security measures designed to protect your information
|
||||
from unauthorized access. Your account is protected by your account
|
||||
password and we urge you to take steps to keep your personal
|
||||
information safe by not disclosing your password and by logging out of
|
||||
your account after each use. We further protect your information from
|
||||
potential security breaches by implementing certain technological
|
||||
security measures including encryption, firewalls and secure socket
|
||||
layer technology. However, these measures do not guarantee that your
|
||||
information will not be accessed, disclosed, altered or destroyed by
|
||||
breach of such firewalls and secure server software. By using our
|
||||
Service, you acknowledge that you understand and agree to assume these
|
||||
risks.
|
||||
</p>
|
||||
<br />
|
||||
<h1 className='text-xl font-semibold text-slate-800'>
|
||||
IV. YOUR RIGHTS REGARDING THE USE OF YOUR PERSONAL INFORMATION
|
||||
</h1>
|
||||
<br />
|
||||
<p className='text-md font-medium text-slate-700'>
|
||||
You have the right at any time to prevent us from contacting you for
|
||||
marketing purposes. When we send a promotional communication to a
|
||||
user, the user can opt out of further promotional communications by
|
||||
following the unsubscribe instructions provided in each promotional
|
||||
e-mail. You can also indicate that you do not wish to receive
|
||||
marketing communications from us by contacting us at{' '}
|
||||
<Link
|
||||
href='mailto:ahmad.khan@outoforgedu.onmicrosoft.com'
|
||||
className='text-blue-600/100 underline'
|
||||
>
|
||||
ahmad.khan@outoforgedu.onmicrosoft.com
|
||||
</Link>
|
||||
. Please note that notwithstanding the promotional preferences you
|
||||
indicate by either unsubscribing or opting out via email, we may
|
||||
continue to send you administrative emails including, for example,
|
||||
periodic updates to our Privacy Policy.
|
||||
</p>
|
||||
<br />
|
||||
<h1 className='text-xl font-semibold text-slate-800'>
|
||||
V. LINKS TO OTHER WEBSITES
|
||||
</h1>
|
||||
<br />
|
||||
<p className='text-md font-medium text-slate-700'>
|
||||
As part of the Service, we may provide links to or compatibility with
|
||||
other websites or applications. However, we are not responsible for
|
||||
the privacy practices employed by those websites or the information or
|
||||
content they contain. This Privacy Policy applies solely to
|
||||
information collected by us through the Site and the Service.
|
||||
Therefore, this Privacy Policy does not apply to your use of a third
|
||||
party website accessed by selecting a link on our Site or via our
|
||||
Service. To the extent that you access or use the Service through or
|
||||
on another website or application, then the privacy policy of that
|
||||
other website or application will apply to your access or use of that
|
||||
site or application. We encourage our users to read the privacy
|
||||
statements of other websites before proceeding to use them.
|
||||
</p>
|
||||
<br />
|
||||
<h1 className='text-xl font-semibold text-slate-800'>
|
||||
VI. CHANGES TO OUR PRIVACY POLICY
|
||||
</h1>
|
||||
<br />
|
||||
<p className='text-md font-medium text-slate-700'>
|
||||
The Company reserves the right to change this policy and our Terms of
|
||||
Service at any time. We will notify you of significant changes to our
|
||||
Privacy Policy by sending a notice to the primary email address
|
||||
specified in your account or by placing a prominent notice on our
|
||||
site. Significant changes will go into effect 30 days following such
|
||||
notification. Non-material changes or clarifications will take effect
|
||||
immediately. You should periodically check the Site and this privacy
|
||||
page for updates.
|
||||
</p>
|
||||
<br />
|
||||
<h1 className='text-xl font-semibold text-slate-800'>
|
||||
VII. CONTACT US
|
||||
</h1>
|
||||
<br />
|
||||
<p className='text-md font-medium text-slate-700'>
|
||||
If you have any questions regarding this Privacy Policy or the
|
||||
practices of this Site, please contact us by sending an email to{' '}
|
||||
<Link
|
||||
href='mailto:ahmad.khan@outoforgedu.onmicrosoft.com'
|
||||
className='text-blue-600/100 underline'
|
||||
>
|
||||
ahmad.khan@outoforgedu.onmicrosoft.com
|
||||
</Link>
|
||||
. Last Updated: This Privacy Policy was last updated on 02/20/2024.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default PrivacyPolicyPage;
|
31
content-collections.ts
Normal file
31
content-collections.ts
Normal file
|
@ -0,0 +1,31 @@
|
|||
import { defineCollection, defineConfig } from '@content-collections/core';
|
||||
import { compileMDX } from '@content-collections/mdx';
|
||||
|
||||
const posts = defineCollection({
|
||||
name: 'BlogPosts',
|
||||
directory: 'app/(main)/blog/posts',
|
||||
include: '*.mdx',
|
||||
schema: (z) => ({
|
||||
title: z
|
||||
.string()
|
||||
.min(3, { message: 'Title must be at least 3 characters' })
|
||||
.max(30, { message: 'Title must be at most 30 characters' }),
|
||||
summary: z
|
||||
.string()
|
||||
.min(10, { message: 'Summary must be at least 10 characters' })
|
||||
.max(50, { message: 'Summary must be at most 50 characters' }),
|
||||
coverImage: z.string(),
|
||||
datePublished: z.string(),
|
||||
}),
|
||||
transform: async (document, context) => {
|
||||
const mdx = await compileMDX(context, document);
|
||||
return {
|
||||
...document,
|
||||
mdx,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export default defineConfig({
|
||||
collections: [posts],
|
||||
});
|
7
mdx-components.tsx
Normal file
7
mdx-components.tsx
Normal file
|
@ -0,0 +1,7 @@
|
|||
import type { MDXComponents } from 'mdx/types';
|
||||
|
||||
export function useMDXComponents(components: MDXComponents): MDXComponents {
|
||||
return {
|
||||
...components,
|
||||
};
|
||||
}
|
|
@ -1,8 +1,12 @@
|
|||
import type { NextConfig } from 'next';
|
||||
|
||||
import { withContentCollections } from '@content-collections/next';
|
||||
import createMDX from '@next/mdx';
|
||||
|
||||
const nextConfig: NextConfig = {
|
||||
experimental: {
|
||||
reactCompiler: true,
|
||||
mdxRs: true,
|
||||
},
|
||||
images: {
|
||||
remotePatterns: [
|
||||
|
@ -16,6 +20,9 @@ const nextConfig: NextConfig = {
|
|||
},
|
||||
],
|
||||
},
|
||||
pageExtensions: ['ts', 'tsx', 'js', 'jsx', 'md', 'mdx'],
|
||||
};
|
||||
|
||||
export default nextConfig;
|
||||
const withMDX = createMDX({});
|
||||
|
||||
export default withContentCollections(withMDX(nextConfig));
|
||||
|
|
23
package.json
23
package.json
|
@ -12,11 +12,14 @@
|
|||
"format:fix": "prettier --write --ignore-path .prettierignore ."
|
||||
},
|
||||
"dependencies": {
|
||||
"@clerk/nextjs": "^6.3.2",
|
||||
"@clerk/nextjs": "^6.3.4",
|
||||
"@hello-pangea/dnd": "^17.0.0",
|
||||
"@liveblocks/client": "^2.11.1",
|
||||
"@liveblocks/client": "^2.12.0",
|
||||
"@liveblocks/node": "^2.11.1",
|
||||
"@liveblocks/react": "^2.11.1",
|
||||
"@mdx-js/loader": "^3.1.0",
|
||||
"@mdx-js/react": "^3.1.0",
|
||||
"@next/mdx": "^15.0.3",
|
||||
"@prisma/client": "^5.22.0",
|
||||
"@prisma/extension-accelerate": "^1.2.1",
|
||||
"@radix-ui/react-accordion": "^1.2.1",
|
||||
|
@ -28,22 +31,21 @@
|
|||
"@radix-ui/react-slot": "^1.1.0",
|
||||
"@radix-ui/react-tooltip": "^1.1.4",
|
||||
"@radix-ui/react-visually-hidden": "^1.1.0",
|
||||
"@tanstack/react-query": "^5.59.20",
|
||||
"@tanstack/react-query": "^5.60.4",
|
||||
"@types/mdx": "^2.0.13",
|
||||
"@vercel/analytics": "^1.4.0",
|
||||
"@vercel/functions": "^1.5.0",
|
||||
"@vercel/speed-insights": "^1.1.0",
|
||||
"babel-plugin-react-compiler": "0.0.0-experimental-7449567-20240905",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^2.1.1",
|
||||
"date-fns": "^4.1.0",
|
||||
"dompurify": "^3.2.0",
|
||||
"eslint-plugin-react-compiler": "0.0.0-experimental-7670337-20240918",
|
||||
"lodash": "^4.17.21",
|
||||
"lucide-react": "^0.456.0",
|
||||
"next": "^15.0.3",
|
||||
"react": "19.0.0-rc.0",
|
||||
"react": "19.0.0-rc.1",
|
||||
"react-day-picker": "^9.3.0",
|
||||
"react-dom": "19.0.0-rc.0",
|
||||
"react-dom": "19.0.0-rc.1",
|
||||
"sharp": "^0.33.5",
|
||||
"sonner": "^1.7.0",
|
||||
"stripe": "^17.3.1",
|
||||
|
@ -55,10 +57,14 @@
|
|||
"zustand": "^5.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@content-collections/core": "^0.7.3",
|
||||
"@content-collections/mdx": "^0.2.0",
|
||||
"@content-collections/next": "^0.2.3",
|
||||
"@eslint/eslintrc": "^3.1.0",
|
||||
"@eslint/js": "^9.14.0",
|
||||
"@microsoft/eslint-formatter-sarif": "^3.1.0",
|
||||
"@next/eslint-plugin-next": "15.0.3",
|
||||
"@tailwindcss/typography": "^0.5.15",
|
||||
"@types/dompurify": "^3",
|
||||
"@types/lodash": "^4.17.13",
|
||||
"@types/node": "^22.9.0",
|
||||
|
@ -67,9 +73,12 @@
|
|||
"@typescript-eslint/eslint-plugin": "^8.14.0",
|
||||
"@typescript-eslint/parser": "^8.14.0",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"babel-plugin-react-compiler": "^19.0.0-beta-a7bf2bd-20241110",
|
||||
"eslint": "^9.14.0",
|
||||
"eslint-config-next": "15.0.3",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-react-compiler": "^19.0.0-beta-a7bf2bd-20241110",
|
||||
"mintlify": "^4.0.273",
|
||||
"postcss": "^8.4.49",
|
||||
"prettier": "^3.3.3",
|
||||
"prettier-plugin-tailwindcss": "^0.6.8",
|
||||
|
|
|
@ -3,10 +3,10 @@ import type { Config } from 'tailwindcss';
|
|||
const config = {
|
||||
darkMode: ['class'],
|
||||
content: [
|
||||
'./pages/**/*.{ts,tsx}',
|
||||
'./components/**/*.{ts,tsx}',
|
||||
'./app/**/*.{ts,tsx}',
|
||||
'./src/**/*.{ts,tsx}',
|
||||
'./pages/**/*.{ts,tsx,md,mdx}',
|
||||
'./components/**/*.{ts,tsx,md,mdx}',
|
||||
'./app/**/*.{ts,tsx,md,mdx}',
|
||||
'./src/**/*.{ts,tsx,md,mdx}',
|
||||
],
|
||||
prefix: '',
|
||||
theme: {
|
||||
|
@ -74,7 +74,7 @@ const config = {
|
|||
},
|
||||
},
|
||||
},
|
||||
plugins: [require('tailwindcss-animate')],
|
||||
plugins: [require('tailwindcss-animate'), require('@tailwindcss/typography')],
|
||||
} satisfies Config;
|
||||
|
||||
export default config;
|
||||
|
|
|
@ -19,7 +19,8 @@
|
|||
}
|
||||
],
|
||||
"paths": {
|
||||
"@/*": ["./*"]
|
||||
"@/*": ["./*"],
|
||||
"content-collections": ["./.content-collections/generated"]
|
||||
},
|
||||
"forceConsistentCasingInFileNames": true
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue