diff --git a/src/actions/README.md b/src/actions/README.md new file mode 100644 index 0000000..67403d3 --- /dev/null +++ b/src/actions/README.md @@ -0,0 +1,8 @@ +## Actions folder + +This folder contains all the server actions that will be used in the app. + +### How to organise this folder + +The name of the file should be similar to the name of the page. +For example, if you want to create a server action for a page called `Dashboard`, the file should be called `dashboard.ts`. So that it is easy to find the actions for a specific page. diff --git a/src/actions/home.ts b/src/actions/home.ts new file mode 100644 index 0000000..ddbf1fe --- /dev/null +++ b/src/actions/home.ts @@ -0,0 +1,25 @@ +'use server'; + +export type PostType = { + id: number; + title: string; + completed: boolean; +}; + +export const getPosts = async () => { + // mimic api call + try { + const response = await fetch( + 'https://jsonplaceholder.typicode.com/todos?_limit=5', + ); + const data = await response.json(); + + return { posts: data as PostType[] }; + } catch (error) { + return { + error: { + message: 'Something went wrong', + }, + }; + } +}; diff --git a/src/app/layout.tsx b/src/app/layout.tsx new file mode 100644 index 0000000..a7a95d5 --- /dev/null +++ b/src/app/layout.tsx @@ -0,0 +1,41 @@ +import { Metadata, Viewport } from 'next'; +import type { PropsWithChildren } from 'react'; + +import { CoreLayout } from '@/common/components/CoreLayout'; +import { Favicon } from '@/common/components/FavIcon'; +import { inter } from '@/common/fonts'; +import '@/common/styles/globals.scss'; + +export const viewport: Viewport = { + themeColor: 'black', +}; + +export const metadata: Metadata = { + title: 'Your App Name | Home', + description: 'Your app description', + metadataBase: new URL('https://google.com'), + openGraph: { + title: 'Your App Name', + description: 'Your app description', + url: 'https://google.com', + siteName: 'Your App Name', + }, + twitter: { + card: 'summary_large_image', + site: '@username', + creator: '@username', + }, +}; + +const GlobalLayout = ({ children }: PropsWithChildren) => { + return ( + + + + {children} + + + ); +}; + +export default GlobalLayout; diff --git a/src/app/not-found.tsx b/src/app/not-found.tsx new file mode 100644 index 0000000..e8117e2 --- /dev/null +++ b/src/app/not-found.tsx @@ -0,0 +1,9 @@ +const Error404 = () => { + return ( +
+ Page not found +
+ ); +}; + +export default Error404; diff --git a/src/app/page.tsx b/src/app/page.tsx new file mode 100644 index 0000000..5bb01d8 --- /dev/null +++ b/src/app/page.tsx @@ -0,0 +1,11 @@ +import { Posts } from '@/modules/Home/Posts'; + +const Homepage = async () => { + return ( +
+ +
+ ); +}; + +export default Homepage; diff --git a/src/common/components/PageHead/PageHead.tsx b/src/common/components/PageHead/PageHead.tsx deleted file mode 100644 index b8e86a2..0000000 --- a/src/common/components/PageHead/PageHead.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import Head from 'next/head'; -import { PropsWithChildren, useMemo } from 'react'; - -export interface PageHeadProps { - name?: string; - description?: string; - removeTitleAppend?: boolean; - titleAppendSeparator?: string; -} - -const appName = 'Your App Here'; - -export const PageHead = ({ - name, - description, - removeTitleAppend = false, - titleAppendSeparator = '|', - children, -}: PropsWithChildren) => { - const pageName = useMemo(() => { - if (!removeTitleAppend) { - return name ? `${name} ${titleAppendSeparator} ${appName}` : appName; - } - return name ?? appName; - }, [name, removeTitleAppend, titleAppendSeparator]); - - const pageDesc = description ?? 'Your app description'; - - return ( - - - - {pageName} - - - - - - - {/* Change this color to match the background of your app */} - {/* It'll appear in places like iOS notch area to make the app look better */} - - {children} - - ); -}; diff --git a/src/common/components/PageHead/index.ts b/src/common/components/PageHead/index.ts deleted file mode 100644 index 4e3cc6c..0000000 --- a/src/common/components/PageHead/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './PageHead'; diff --git a/src/common/fonts/index.ts b/src/common/fonts/index.ts new file mode 100644 index 0000000..4232d22 --- /dev/null +++ b/src/common/fonts/index.ts @@ -0,0 +1 @@ +export * from './urbanist'; diff --git a/src/common/fonts/urbanist.ts b/src/common/fonts/urbanist.ts new file mode 100644 index 0000000..1ad2cb9 --- /dev/null +++ b/src/common/fonts/urbanist.ts @@ -0,0 +1,6 @@ +import { Urbanist } from 'next/font/google'; + +export const inter = Urbanist({ + subsets: ['latin'], + variable: '--font-urbanist', +}); diff --git a/src/modules/Home/Post.tsx b/src/modules/Home/Post.tsx new file mode 100644 index 0000000..dc80b67 --- /dev/null +++ b/src/modules/Home/Post.tsx @@ -0,0 +1,19 @@ +'use client'; + +import { PostType } from '@/actions/home'; + +interface PostProps { + post: PostType; +} + +export const Post = ({ post }: PostProps) => { + return ( +
+

{post.title}

+

{post.completed ? '✅' : '❌'}

+
+ ); +}; diff --git a/src/modules/Home/Posts.tsx b/src/modules/Home/Posts.tsx new file mode 100644 index 0000000..4461e7a --- /dev/null +++ b/src/modules/Home/Posts.tsx @@ -0,0 +1,22 @@ +import { Post } from '@/modules/Home/Post'; + +import { getPosts } from '@/actions/home'; + +export const Posts = async () => { + const data = await getPosts(); + + if (data.posts) { + const posts = data.posts.map((post) => { + return ; + }); + + return ( +
+

Posts

+
{posts}
+
+ ); + } + + return <>{data.error.message}; +}; diff --git a/src/pages/404.tsx b/src/pages/404.tsx deleted file mode 100644 index e4fbc3b..0000000 --- a/src/pages/404.tsx +++ /dev/null @@ -1,11 +0,0 @@ -const Error404 = () => { - return ( -
-

- 404: Page not found -

-
- ); -}; - -export default Error404; diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx deleted file mode 100644 index c312690..0000000 --- a/src/pages/_app.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import '@/common/styles/globals.scss'; - -import { type NextComponentType } from 'next'; -import { type AppProps } from 'next/app'; - -import { CoreLayout } from '@/common/components/CoreLayout'; -import { PageHead } from '@/common/components/PageHead'; - -type ComponentProps = { - layout?: () => JSX.Element; -} & NextComponentType; - -export const App = ({ Component, pageProps }: AppProps) => { - const Layout = (Component as ComponentProps).layout ?? CoreLayout; - return ( - <> - - - - - - ); -}; - -export default App; diff --git a/src/pages/_document.tsx b/src/pages/_document.tsx deleted file mode 100644 index ac540ab..0000000 --- a/src/pages/_document.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import Document, { Head, Html, Main, NextScript } from 'next/document'; - -import { Favicon } from '@/common/components/FavIcon'; - -class MyDocument extends Document { - render() { - return ( - - - - - -
- - - - ); - } -} - -export default MyDocument; diff --git a/src/pages/index.tsx b/src/pages/index.tsx deleted file mode 100644 index af91f8e..0000000 --- a/src/pages/index.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { PageHead } from '@/common/components/PageHead'; - -export default function Home() { - return ( -
- -
- Hello world -
-
- ); -} diff --git a/tailwind.config.ts b/tailwind.config.ts index 8778d40..5526291 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -1,11 +1,17 @@ -import type { Config } from "tailwindcss"; +import type { Config } from 'tailwindcss'; +import { fontFamily } from 'tailwindcss/defaultTheme'; -export default { - content: ["./src/**/*.{js,ts,jsx,tsx}"], +const tailwindConfig = { + content: ['./src/**/*.{js,ts,jsx,tsx}'], theme: { extend: { + fontFamily: { + sans: ['var(--font-urbanist)', 'Urbanist', ...fontFamily.sans], + }, colors: {}, }, }, plugins: [], } satisfies Config; + +export default tailwindConfig; diff --git a/tsconfig.json b/tsconfig.json index 9251a86..68e2a73 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -16,9 +16,16 @@ "jsx": "preserve", "baseUrl": ".", "paths": { - "@/*": ["src/*"] - } + "@/*": ["src/*"], + }, }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "**/*.js", "./**/.*"], - "exclude": ["node_modules"] + "include": [ + "next-env.d.ts", + "**/*.ts", + "**/*.tsx", + "**/*.js", + "./**/.*", + ".next/types/**/*.ts", + ], + "exclude": ["node_modules"], }