diff --git a/.eslintrc.json b/.eslintrc.json
index b4e3b62..a4f9320 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -1,8 +1,10 @@
{
- "extends": ["next", "prettier"],
+ "extends": ["next/core-web-vitals", "next/typescript", "prettier"],
"rules": {
"react/no-unescaped-entities": "off",
"react-hooks/exhaustive-deps": "off",
- "@next/next/no-img-element": "off"
+ "@next/next/no-img-element": "off",
+ "@typescript-eslint/no-explicit-any": "off",
+ "@typescript-eslint/no-empty-object-type": "off"
}
}
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yaml
similarity index 100%
rename from .github/FUNDING.yml
rename to .github/FUNDING.yaml
diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml
index 60ffd43..44c3182 100644
--- a/.github/dependabot.yaml
+++ b/.github/dependabot.yaml
@@ -21,4 +21,4 @@ updates:
prefix: 'npm'
include: 'scope'
labels:
- - '📦 dependencies'
+ - 'dependencies'
diff --git a/.github/workflows/beautify.yml b/.github/workflows/beautify.yaml
similarity index 100%
rename from .github/workflows/beautify.yml
rename to .github/workflows/beautify.yaml
diff --git a/.github/workflows/lighthouse.yml b/.github/workflows/lighthouse.yaml
similarity index 95%
rename from .github/workflows/lighthouse.yml
rename to .github/workflows/lighthouse.yaml
index 658f4eb..e965063 100644
--- a/.github/workflows/lighthouse.yml
+++ b/.github/workflows/lighthouse.yaml
@@ -10,7 +10,7 @@ name: Lighthouse
on:
workflow_dispatch:
workflow_run:
- workflows: ['Web Production']
+ workflows: ['Release & Publish']
types:
- completed
push:
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
new file mode 100644
index 0000000..dfc79e6
--- /dev/null
+++ b/.github/workflows/release.yaml
@@ -0,0 +1,75 @@
+# Deploy the web application
+# into the vercel as production
+#
+# ***** NOTE ******
+# This deployment need to setup some secrets
+
+name: Release & Publish
+
+env:
+ VERCEL_ORG_ID: ${{ secrets.VERCEL_WEB_ORG_ID }}
+ VERCEL_PROJECT_ID: ${{ secrets.VERCEL_WEB_PROJECT_ID }}
+
+on:
+ push:
+ tags:
+ - 'v*'
+
+permissions:
+ contents: write
+
+jobs:
+ release:
+ name: Release
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout Code
+ uses: actions/checkout@v4
+
+ - name: Create Release
+ uses: softprops/action-gh-release@v2
+ with:
+ tag_name: ${{ github.ref_name }}
+ name: '${{ github.ref_name }}'
+ generate_release_notes: true
+ draft: false
+ prerelease: false
+
+ publish:
+ name: Publish Website
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout the code
+ uses: actions/checkout@v4
+
+ - name: Setup Bun Environment
+ uses: oven-sh/setup-bun@v2
+ with:
+ bun-version: latest
+
+ - name: Install Vercel CLI
+ run: bun add --global vercel@latest
+
+ - name: Pull Vercel Environment Information
+ run: vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}
+
+ - name: Build Project Artifacts
+ run: vercel build --prod --token=${{ secrets.VERCEL_TOKEN }}
+
+ - name: Deploy Project Artifacts to Vercel
+ run: vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }}
+
+ generate-changelog:
+ name: Generate Changelog
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+
+ - name: Update changelog
+ uses: BobAnkh/auto-generate-changelog@v1.2.5
+ with:
+ ACCESS_TOKEN: ${{secrets.GITHUB_TOKEN}}
+ COMMIT_MESSAGE: '🔖 docs(CHANGELOG): update release notes'
+ TYPE: 'feat:Feature,fix:Bug Fixes,docs:Documentation,refactor:Refactor,perf:Performance Improvements'
diff --git a/.github/workflows/web-production.yml b/.github/workflows/web-production.yml
deleted file mode 100644
index 8481524..0000000
--- a/.github/workflows/web-production.yml
+++ /dev/null
@@ -1,50 +0,0 @@
-# Deploy the web application
-# into the vercel as production
-#
-# ***** NOTE ******
-# This deployment need to setup some secrets
-
-name: Web Production
-
-# define the env for this workflows
-env:
- VERCEL_ORG_ID: ${{ secrets.VERCEL_WEB_ORG_ID }}
- VERCEL_PROJECT_ID: ${{ secrets.VERCEL_WEB_PROJECT_ID }}
-
-# Oonly run this workflows if
-# the user start manual the actions
-# and push the code into the main branch
-on:
- workflow_dispatch:
- workflow_run:
- workflows: ['Beautify Code']
- types:
- - completed
- push:
- branches: ['main']
-
-jobs:
- update:
- name: Update Web App
- runs-on: ubuntu-latest
- if: ${{ github.event.workflow_run.conclusion == 'success' }}
- steps:
- - name: Checkout the code
- uses: actions/checkout@v4
-
- - name: Setup Bun Environment
- uses: oven-sh/setup-bun@v2
- with:
- bun-version: latest
-
- - name: Install Vercel CLI
- run: bun add --global vercel@latest
-
- - name: Pull Vercel Environment Information
- run: vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}
-
- - name: Build Project Artifacts
- run: vercel build --prod --token=${{ secrets.VERCEL_TOKEN }}
-
- - name: Deploy Project Artifacts to Vercel
- run: vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }}
diff --git a/bun.lockb b/bun.lockb
index b798fc1..0985a2a 100755
Binary files a/bun.lockb and b/bun.lockb differ
diff --git a/data/bio.json b/data/bio.json
new file mode 100644
index 0000000..0f60ae1
--- /dev/null
+++ b/data/bio.json
@@ -0,0 +1,60 @@
+{
+ "links": [
+ {
+ "type": "link",
+ "url": "/contact",
+ "label": "Hire me"
+ },
+ {
+ "type": "link",
+ "url": "/contact",
+ "label": "Become partner (business)",
+ "className": "tablet:row-span-2"
+ },
+ {
+ "type": "link",
+ "url": "/works",
+ "label": " See my works",
+ "className": "tablet:row-span-2"
+ },
+ {
+ "type": "link",
+ "url": "https://nyomansunima.lemonsqueezy.com?ref=nyomansunima",
+ "label": "Check my goodies"
+ },
+ {
+ "type": "link",
+ "url": "https://tryweebo.one?ref=nyomansunima",
+ "label": "My web design business (NEW)",
+ "className": "tablet:row-span-2"
+ },
+ {
+ "type": "link",
+ "url": "https://ko-fi.com/nyomansunima?ref=nyomansunima",
+ "label": "Suport me by donation"
+ },
+ {
+ "type": "link",
+ "url": "/stories",
+ "label": "Learn together with me"
+ },
+ {
+ "type": "link",
+ "url": "https://moono.space?ref=nyomansunima",
+ "label": "My apps collection (NEW)",
+ "className": "tablet:col-span-2"
+ },
+ {
+ "type": "link",
+ "url": "https://weecraft.club?ref=nyomansunima",
+ "label": "See tiny dev resources (NEW)",
+ "className": "tablet:col-span-2"
+ },
+ {
+ "type": "link",
+ "url": "/crafts",
+ "label": "See all of my crafts",
+ "className": "tablet:col-span-2"
+ }
+ ]
+}
diff --git a/src/features/contact/data.json b/data/contact.json
similarity index 100%
rename from src/features/contact/data.json
rename to data/contact.json
diff --git a/src/features/crafts/data.json b/data/crafts.json
similarity index 100%
rename from src/features/crafts/data.json
rename to data/crafts.json
diff --git a/src/features/faqs/data.json b/data/faqs.json
similarity index 100%
rename from src/features/faqs/data.json
rename to data/faqs.json
diff --git a/src/features/journeys/data.json b/data/journeys.json
similarity index 100%
rename from src/features/journeys/data.json
rename to data/journeys.json
diff --git a/src/features/resources/data.json b/data/resources.json
similarity index 100%
rename from src/features/resources/data.json
rename to data/resources.json
diff --git a/src/features/stories/data.json b/data/stories.json
similarity index 100%
rename from src/features/stories/data.json
rename to data/stories.json
diff --git a/src/features/works/data.json b/data/works.json
similarity index 100%
rename from src/features/works/data.json
rename to data/works.json
diff --git a/data/works/brook-code-theme.mdx b/data/works/brook-code-theme.mdx
new file mode 100644
index 0000000..b5d2a17
--- /dev/null
+++ b/data/works/brook-code-theme.mdx
@@ -0,0 +1,5 @@
+---
+tags: ['developers', 'designer']
+---
+
+# Hero
diff --git a/next.config.ts b/next.config.ts
index c598fa4..a689337 100644
--- a/next.config.ts
+++ b/next.config.ts
@@ -1,6 +1,10 @@
import { NextConfig } from 'next'
const nextConfig: NextConfig = {
+ experimental: {
+ optimizePackageImports: ['@flaticon/flaticon-uicons'],
+ },
+ pageExtensions: ['js', 'jsx', 'md', 'mdx', 'ts', 'tsx'],
images: {
remotePatterns: [
{ hostname: 'cdn.dribbble.com' },
@@ -8,6 +12,8 @@ const nextConfig: NextConfig = {
{ hostname: 'images.unsplash.com' },
],
},
+ skipTrailingSlashRedirect: true,
+ transpilePackages: [],
}
export default nextConfig
diff --git a/package.json b/package.json
index 1b1fc38..180922e 100644
--- a/package.json
+++ b/package.json
@@ -3,7 +3,7 @@
"version": "0.0.0",
"private": true,
"scripts": {
- "dev": "next dev --turbo",
+ "dev": "next dev --turbopack",
"build": "next build",
"start": "next start",
"lint:check": "next lint",
@@ -20,35 +20,41 @@
"@radix-ui/react-label": "^2.1.0",
"@radix-ui/react-slot": "^1.1.0",
"@radix-ui/react-tooltip": "^1.1.2",
+ "@tailwindcss/forms": "^0.5.9",
+ "@tanstack/react-query": "^5.62.0",
"@vercel/analytics": "^1.3.1",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"date-fns": "^4.1.0",
- "framer-motion": "^11.3.21",
- "geist": "^1.3.1",
"lenis": "^1.1.6",
- "next": "^15.0.2",
+ "next": "15.0.3",
"next-themes": "^0.4.3",
- "plaiceholder": "^3.0.0",
- "react": "^18.3.1",
- "react-dom": "^18.3.1",
+ "posthog-js": "^1.194.0",
+ "react": "19.0.0-rc-66855b96-20241106",
+ "react-dom": "19.0.0-rc-66855b96-20241106",
"react-hook-form": "^7.52.2",
"sonner": "^1.5.0",
"tailwind-merge": "^2.4.0",
+ "tailwindcss-animate": "^1.0.7",
"zod": "^3.23.8"
},
"devDependencies": {
"@tailwindcss/typography": "^0.5.13",
+ "@tanstack/react-query-devtools": "^5.62.0",
"@types/node": "^22",
- "@types/react": "^18",
- "@types/react-dom": "^18",
+ "@types/react": "npm:types-react@19.0.0-rc.1",
+ "@types/react-dom": "npm:types-react-dom@19.0.0-rc.1",
"autoprefixer": "^10",
"eslint": "^9.13.0",
- "eslint-config-next": "^15.0.2",
+ "eslint-config-next": "15.0.3",
"eslint-config-prettier": "^9.1.0",
"postcss": "^8",
"prettier": "^3.3.3",
"tailwindcss": "^3",
"typescript": "^5"
+ },
+ "overrides": {
+ "@types/react": "npm:types-react@19.0.0-rc.1",
+ "@types/react-dom": "npm:types-react-dom@19.0.0-rc.1"
}
}
diff --git a/src/app/(home)/page.tsx b/src/app/(home)/page.tsx
index 3cd9f8e..dd6a74d 100644
--- a/src/app/(home)/page.tsx
+++ b/src/app/(home)/page.tsx
@@ -1,23 +1,20 @@
import * as React from 'react'
import { Metadata } from 'next'
-import {
- defaultOpenGraphMetadata,
- defaultTwitterMetadata,
-} from '@shared/lib/shared-metadata'
-import { ResourcesSection, HeroSection } from '@features/home'
+import * as defaultMetadata from '@shared/libs/shared-metadata'
+import { BioSection, HeroSection } from '@features/home'
export const metadata: Metadata = {
title: 'Nyoman Sunima',
description:
'Focused on crafting digital products, website, web app, mobile app to help business.',
openGraph: {
- ...defaultOpenGraphMetadata,
+ ...defaultMetadata.openGraph,
title: 'Nyoman Sunima',
description:
'Focused on crafting digital products, website, web app, mobile app to help business.',
},
twitter: {
- ...defaultTwitterMetadata,
+ ...defaultMetadata.twitter,
title: 'Nyoman Sunima',
description:
'Focused on crafting digital products, website, web app, mobile app to help business.',
@@ -28,7 +25,7 @@ export default function HomePage(): React.ReactElement {
return (
-
+
)
}
diff --git a/src/app/about/page.tsx b/src/app/about/page.tsx
index d876747..1366b78 100644
--- a/src/app/about/page.tsx
+++ b/src/app/about/page.tsx
@@ -1,8 +1,6 @@
+import * as React from 'react'
import { Metadata } from 'next'
-import {
- defaultOpenGraphMetadata,
- defaultTwitterMetadata,
-} from '@shared/lib/shared-metadata'
+import * as defaultMetadata from '@shared/libs/shared-metadata'
import {
DetailSection,
SharingSection,
@@ -11,19 +9,19 @@ import {
AchievementSection,
EndWordSection,
} from '@features/about'
-import { ArticleContent } from '@shared/components/content'
+import { ArticleContent } from '@shared/components/common/content'
export const metadata: Metadata = {
title: 'About',
description: 'The whole story about me, nyoman sunima and all of the journey',
openGraph: {
- ...defaultOpenGraphMetadata,
+ ...defaultMetadata.openGraph,
title: 'About',
description:
'The whole story about me, nyoman sunima and all of the journey',
},
twitter: {
- ...defaultTwitterMetadata,
+ ...defaultMetadata.twitter,
title: 'About',
description:
'The whole story about me, nyoman sunima and all of the journey',
diff --git a/src/app/contact/page.tsx b/src/app/contact/page.tsx
index b487593..a00deb5 100644
--- a/src/app/contact/page.tsx
+++ b/src/app/contact/page.tsx
@@ -1,21 +1,18 @@
import * as React from 'react'
import { Metadata } from 'next'
-import {
- defaultOpenGraphMetadata,
- defaultTwitterMetadata,
-} from '@shared/lib/shared-metadata'
+import * as defaultMetadata from '@shared/libs/shared-metadata'
import { ContactList, SocialMediaList } from '@features/contact'
export const metadata: Metadata = {
title: 'Contact',
description: 'Get in touch with me right now, start your idea',
openGraph: {
- ...defaultOpenGraphMetadata,
+ ...defaultMetadata.openGraph,
title: 'Contact',
description: 'Get in touch with me right now, start your idea',
},
twitter: {
- ...defaultTwitterMetadata,
+ ...defaultMetadata.twitter,
title: 'Contact',
description: 'Get in touch with me right now, start your idea',
},
diff --git a/src/app/crafts/page.tsx b/src/app/crafts/page.tsx
index 0ef646c..8282f74 100644
--- a/src/app/crafts/page.tsx
+++ b/src/app/crafts/page.tsx
@@ -1,9 +1,6 @@
import * as React from 'react'
import { Metadata } from 'next'
-import {
- defaultOpenGraphMetadata,
- defaultTwitterMetadata,
-} from '@shared/lib/shared-metadata'
+import * as defaultMetadata from '@shared/libs/shared-metadata'
import { CraftListSection } from '@features/crafts'
export const metadata: Metadata = {
@@ -11,13 +8,13 @@ export const metadata: Metadata = {
description:
'See all of my projects, business, products, side husltes and something that i built',
openGraph: {
- ...defaultOpenGraphMetadata,
+ ...defaultMetadata.openGraph,
title: 'Crafts',
description:
'See all of my projects, business, products, side husltes and something that i built',
},
twitter: {
- ...defaultTwitterMetadata,
+ ...defaultMetadata.twitter,
title: 'Crafts',
description:
'See all of my projects, business, products, side husltes and something that i built',
diff --git a/src/app/faqs/page.tsx b/src/app/faqs/page.tsx
index 0dbc709..06d8206 100644
--- a/src/app/faqs/page.tsx
+++ b/src/app/faqs/page.tsx
@@ -1,21 +1,18 @@
import * as React from 'react'
import { Metadata } from 'next'
-import {
- defaultOpenGraphMetadata,
- defaultTwitterMetadata,
-} from '@shared/lib/shared-metadata'
+import * as defaultMetadata from '@shared/libs/shared-metadata'
import { FAQListSection, AskSection } from '@features/faqs'
export const metadata: Metadata = {
title: 'FAQs',
description: 'Most asked questions by people around the world',
openGraph: {
- ...defaultOpenGraphMetadata,
+ ...defaultMetadata.openGraph,
title: 'FAQs',
description: 'Most asked questions by people around the world',
},
twitter: {
- ...defaultTwitterMetadata,
+ ...defaultMetadata.twitter,
title: 'FAQs',
description: 'Most asked questions by people around the world',
},
diff --git a/src/app/global-error.tsx b/src/app/global-error.tsx
index 68b03f4..8ea6882 100644
--- a/src/app/global-error.tsx
+++ b/src/app/global-error.tsx
@@ -1,13 +1,11 @@
'use client'
import '@shared/styles/globals.css'
-import { GeistSans } from 'geist/font/sans'
-import { GeistMono } from 'geist/font/mono'
import { Button } from '@shared/components/ui/button'
-import { CenteredLayout } from '@shared/components/centered-layout'
+import { CenteredLayout } from '@shared/components//common/centered-layout'
+import * as fonts from '@shared/fonts'
export default function GlobalError({
- error,
reset,
}: {
error: Error & { digest?: string }
@@ -17,7 +15,7 @@ export default function GlobalError({
diff --git a/src/app/journeys/page.tsx b/src/app/journeys/page.tsx
index 0c74e80..007fa6c 100644
--- a/src/app/journeys/page.tsx
+++ b/src/app/journeys/page.tsx
@@ -1,20 +1,17 @@
import { Metadata } from 'next'
-import {
- defaultOpenGraphMetadata,
- defaultTwitterMetadata,
-} from '@shared/lib/shared-metadata'
+import * as defaultMetadata from '@shared/libs/shared-metadata'
import { ExperienceSection, LogListSection } from '@features/journeys'
export const metadata: Metadata = {
title: 'Journeys',
description: 'The whole story of me, nyoman sunima and all of the journey',
openGraph: {
- ...defaultOpenGraphMetadata,
+ ...defaultMetadata.openGraph,
title: 'Journeys',
description: 'The whole story of me, nyoman sunima and all of the journey',
},
twitter: {
- ...defaultTwitterMetadata,
+ ...defaultMetadata.twitter,
title: 'Journeys',
description: 'The whole story of me, nyoman sunima and all of the journey',
},
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index ae18440..9e5a44e 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -1,19 +1,18 @@
import * as React from 'react'
import type { Metadata } from 'next'
import '@shared/styles/globals.css'
-import { config } from '@shared/lib/config'
-import { Analytics } from '@vercel/analytics/react'
-import { GeistSans } from 'geist/font/sans'
-import { GeistMono } from 'geist/font/mono'
-import { AnimationProvider } from '@shared/provider/animation-provider'
-import { ThemeProvider } from '@shared/provider/theme-provider'
-import Header from '@shared/components/header'
-import Footer from '@shared/components/footer'
+import config from '@shared/libs/config'
+import { Analytics as VercelAnalytics } from '@vercel/analytics/react'
+import { AnimationProvider } from '@shared/providers/animation-provider'
+import { ThemeProvider } from '@shared/providers/theme-provider'
+import Header from '@shared/components/common/header'
+import Footer from '@shared/components/common/footer'
import { Toaster } from '@shared/components/ui/toast'
-import { CenteredLayout } from '@shared/components/centered-layout'
-import { GoogleAnalyticsScript } from '@shared/components/script-tag'
+import { CenteredLayout } from '@shared/components/common/centered-layout'
+import { PosthogProvider } from '@shared/providers/posthog-provider'
+import { QueryProvider } from '@shared/providers/query-provider'
+import * as fonts from '@shared/fonts'
-// default metadata for the site
export const metadata: Metadata = {
applicationName: 'Nyoman Sunima',
keywords: [
@@ -35,7 +34,7 @@ export const metadata: Metadata = {
creator: 'Nyoman Sunima',
metadataBase: new URL(config.app.host),
verification: {
- google: 'fTZZv4lCZ2_i8jo8FFKuXc6Acuy8jMClhwDzRX64NgE',
+ google: config.verification.google,
},
}
@@ -48,31 +47,34 @@ export default function RootLayout({
-
-
-
-
-
-
-
- {children}
-
-
-
+
+
+
+
+
+
+
+
+ {children}
+
+
+
-
-
-
+
+
+
+
-
-
+
+
+
)
}
diff --git a/src/app/privacy/page.tsx b/src/app/privacy/page.tsx
index e599d98..3da9362 100644
--- a/src/app/privacy/page.tsx
+++ b/src/app/privacy/page.tsx
@@ -1,22 +1,19 @@
import * as React from 'react'
import { Metadata } from 'next'
-import {
- defaultOpenGraphMetadata,
- defaultTwitterMetadata,
-} from '@shared/lib/shared-metadata'
+import * as defaultMetadata from '@shared/libs/shared-metadata'
import Link from 'next/link'
-import { ArticleContent } from '@shared/components/content'
+import { ArticleContent } from '@shared/components/common/content'
export const metadata: Metadata = {
title: 'Privacy Policy',
description: 'Read the privacy policy for this site',
openGraph: {
- ...defaultOpenGraphMetadata,
+ ...defaultMetadata.openGraph,
title: 'Privacy Policy',
description: 'Read the privacy policy for this site',
},
twitter: {
- ...defaultTwitterMetadata,
+ ...defaultMetadata.twitter,
title: 'Privacy Policy',
description: 'Read the privacy policy for this site',
},
diff --git a/src/app/resources/page.tsx b/src/app/resources/page.tsx
index 02e8998..e152b2d 100644
--- a/src/app/resources/page.tsx
+++ b/src/app/resources/page.tsx
@@ -1,21 +1,18 @@
import * as React from 'react'
import { Metadata } from 'next'
-import {
- defaultOpenGraphMetadata,
- defaultTwitterMetadata,
-} from '@shared/lib/shared-metadata'
+import * as defaultMetadata from '@shared/libs/shared-metadata'
import { SourcesSection } from '@features/resources'
export const metadata: Metadata = {
title: 'Resources',
description: 'Get free resources and things that help your works',
openGraph: {
- ...defaultOpenGraphMetadata,
+ ...defaultMetadata.openGraph,
title: 'Resources',
description: 'Get free resources and things that help your works',
},
twitter: {
- ...defaultTwitterMetadata,
+ ...defaultMetadata.twitter,
title: 'Resources',
description: 'Get free resources and things that help your works',
},
diff --git a/src/app/stories/page.tsx b/src/app/stories/page.tsx
index 9cac81f..402dbaa 100644
--- a/src/app/stories/page.tsx
+++ b/src/app/stories/page.tsx
@@ -1,9 +1,6 @@
import * as React from 'react'
import { Metadata } from 'next'
-import {
- defaultOpenGraphMetadata,
- defaultTwitterMetadata,
-} from '@shared/lib/shared-metadata'
+import * as defaultMetadata from '@shared/libs/shared-metadata'
import { PublicationSection, RecentlySection } from '@features/stories'
export const metadata: Metadata = {
@@ -11,13 +8,13 @@ export const metadata: Metadata = {
description:
'Everyday i write, record, and create any resources to sharing into the social media and community platforms',
openGraph: {
- ...defaultOpenGraphMetadata,
+ ...defaultMetadata.openGraph,
title: 'Stories',
description:
'Everyday i write, record, and create any resources to sharing into the social media and community platforms',
},
twitter: {
- ...defaultTwitterMetadata,
+ ...defaultMetadata.twitter,
title: 'Stories',
description:
'Everyday i write, record, and create any resources to sharing into the social media and community platforms',
diff --git a/src/app/template.tsx b/src/app/template.tsx
index 65f502a..0b390e6 100644
--- a/src/app/template.tsx
+++ b/src/app/template.tsx
@@ -1,5 +1,5 @@
import * as React from 'react'
-import { PageTransition } from '@shared/components/transition'
+import { PageTransition } from '@shared/components/animation/transition'
interface RootTemplateProps {
children: React.ReactNode
diff --git a/src/app/terms/page.tsx b/src/app/terms/page.tsx
index 5e906fd..726d754 100644
--- a/src/app/terms/page.tsx
+++ b/src/app/terms/page.tsx
@@ -1,22 +1,19 @@
import * as React from 'react'
import { Metadata } from 'next'
-import {
- defaultOpenGraphMetadata,
- defaultTwitterMetadata,
-} from '@shared/lib/shared-metadata'
+import * as defaultMetadata from '@shared/libs/shared-metadata'
import Link from 'next/link'
-import { ArticleContent } from '@shared/components/content'
+import { ArticleContent } from '@shared/components/common/content'
export const metadata: Metadata = {
title: 'Terms of use',
description: 'Read the terms of use for this site',
openGraph: {
- ...defaultOpenGraphMetadata,
+ ...defaultMetadata.openGraph,
title: 'Terms of use',
description: 'Read the terms of use for this site',
},
twitter: {
- ...defaultTwitterMetadata,
+ ...defaultMetadata.twitter,
title: 'Terms of use',
description: 'Read the terms of use for this site',
},
diff --git a/src/app/works/[slug]/page.tsx b/src/app/works/[slug]/page.tsx
new file mode 100644
index 0000000..acdc513
--- /dev/null
+++ b/src/app/works/[slug]/page.tsx
@@ -0,0 +1,25 @@
+import * as React from 'react'
+import { Metadata } from 'next'
+import * as defaultMetadata from '@shared/libs/shared-metadata'
+
+export const metadata: Metadata = {
+ title: 'Works',
+ description:
+ 'See all of my works including projects, apps, products, case studies, idea and playground',
+ openGraph: {
+ ...defaultMetadata.openGraph,
+ title: 'Works',
+ description:
+ 'See all of my works including projects, apps, products, case studies, idea and playground',
+ },
+ twitter: {
+ ...defaultMetadata.twitter,
+ title: 'Works',
+ description:
+ 'See all of my works including projects, apps, products, case studies, idea and playground',
+ },
+}
+
+export default function WorksDetailPage(): React.ReactElement {
+ return
+}
diff --git a/src/app/works/page.tsx b/src/app/works/page.tsx
index 23318ee..0ce69c9 100644
--- a/src/app/works/page.tsx
+++ b/src/app/works/page.tsx
@@ -1,9 +1,6 @@
import * as React from 'react'
import { Metadata } from 'next'
-import {
- defaultOpenGraphMetadata,
- defaultTwitterMetadata,
-} from '@shared/lib/shared-metadata'
+import * as defaultMetadata from '@shared/libs/shared-metadata'
import { WorksListSection, ComingSoonSection } from '@features/works'
export const metadata: Metadata = {
@@ -11,13 +8,13 @@ export const metadata: Metadata = {
description:
'See all of my works including projects, apps, products, case studies, idea and playground',
openGraph: {
- ...defaultOpenGraphMetadata,
+ ...defaultMetadata.openGraph,
title: 'Works',
description:
'See all of my works including projects, apps, products, case studies, idea and playground',
},
twitter: {
- ...defaultTwitterMetadata,
+ ...defaultMetadata.twitter,
title: 'Works',
description:
'See all of my works including projects, apps, products, case studies, idea and playground',
diff --git a/src/features/about/components/achievement.tsx b/src/features/about/achievement-section.tsx
similarity index 100%
rename from src/features/about/components/achievement.tsx
rename to src/features/about/achievement-section.tsx
diff --git a/src/features/about/components/activity.tsx b/src/features/about/activity-section.tsx
similarity index 97%
rename from src/features/about/components/activity.tsx
rename to src/features/about/activity-section.tsx
index 7890ae5..0c519e9 100644
--- a/src/features/about/components/activity.tsx
+++ b/src/features/about/activity-section.tsx
@@ -1,5 +1,5 @@
import * as React from 'react'
-import { ContentImage } from '@shared/components/content'
+import { ContentImage } from '@shared/components/common/content'
export function ActivitySection(): React.ReactElement {
return (
diff --git a/src/features/about/components/detail.tsx b/src/features/about/detail-section.tsx
similarity index 97%
rename from src/features/about/components/detail.tsx
rename to src/features/about/detail-section.tsx
index ae35369..f6650cf 100644
--- a/src/features/about/components/detail.tsx
+++ b/src/features/about/detail-section.tsx
@@ -1,6 +1,9 @@
import Link from 'next/link'
import * as React from 'react'
-import { ContentImage, GalleryListImage } from '@shared/components/content'
+import {
+ ContentImage,
+ GalleryListImage,
+} from '@shared/components/common/content'
const images = [
'https://images.unsplash.com/photo-1537996194471-e657df975ab4?q=80&w=2838&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
diff --git a/src/features/about/components/endword.tsx b/src/features/about/endword-section.tsx
similarity index 100%
rename from src/features/about/components/endword.tsx
rename to src/features/about/endword-section.tsx
diff --git a/src/features/about/index.ts b/src/features/about/index.ts
index 8772337..97a83d9 100644
--- a/src/features/about/index.ts
+++ b/src/features/about/index.ts
@@ -1,6 +1,6 @@
-export * from './components/activity'
-export * from './components/detail'
-export * from './components/sharing'
-export * from './components/indie'
-export * from './components/achievement'
-export * from './components/endword'
+export * from './activity-section'
+export * from './detail-section'
+export * from './sharing-section'
+export * from './indie-section'
+export * from './achievement-section'
+export * from './endword-section'
diff --git a/src/features/about/components/indie.tsx b/src/features/about/indie-section.tsx
similarity index 100%
rename from src/features/about/components/indie.tsx
rename to src/features/about/indie-section.tsx
diff --git a/src/features/about/components/sharing.tsx b/src/features/about/sharing-section.tsx
similarity index 96%
rename from src/features/about/components/sharing.tsx
rename to src/features/about/sharing-section.tsx
index ff86017..ec48c5e 100644
--- a/src/features/about/components/sharing.tsx
+++ b/src/features/about/sharing-section.tsx
@@ -1,5 +1,5 @@
import * as React from 'react'
-import { ContentImage } from '@shared/components/content'
+import { ContentImage } from '@shared/components/common/content'
export function SharingSection(): React.ReactElement {
return (
diff --git a/src/features/contact/components/contact-item.tsx b/src/features/contact/contact-item.tsx
similarity index 100%
rename from src/features/contact/components/contact-item.tsx
rename to src/features/contact/contact-item.tsx
diff --git a/src/features/contact/components/contact-list.tsx b/src/features/contact/contact-list.tsx
similarity index 62%
rename from src/features/contact/components/contact-list.tsx
rename to src/features/contact/contact-list.tsx
index 9db849c..3ebb3fe 100644
--- a/src/features/contact/components/contact-list.tsx
+++ b/src/features/contact/contact-list.tsx
@@ -1,8 +1,8 @@
import * as React from 'react'
-import jsonData from '../data.json'
-import { ContactItem, ContactItemData } from './contact-item'
+import { ContactItem } from './contact-item'
+import * as contactService from './contact-service'
-const contacts: ContactItemData[] = jsonData.contacts as ContactItemData[]
+const contacts = await contactService.getContacts()
export function ContactList() {
return (
diff --git a/src/features/contact/contact-service.ts b/src/features/contact/contact-service.ts
new file mode 100644
index 0000000..90f844f
--- /dev/null
+++ b/src/features/contact/contact-service.ts
@@ -0,0 +1,31 @@
+'use server'
+
+import config from '@shared/libs/config'
+import { ContactItemData } from './contact-item'
+import { githubDataClient, localDataClient } from '@shared/libs/connections'
+import { SocialData } from './social-item'
+
+const filePath = '/contact.json'
+const isProduction = config.isProduction
+
+export async function getContacts(): Promise {
+ let res: any
+ if (isProduction) {
+ res = await githubDataClient(filePath)
+ } else {
+ res = await localDataClient(filePath)
+ }
+
+ return res.contacts as ContactItemData[]
+}
+
+export async function getSocials(): Promise {
+ let res: any
+ if (isProduction) {
+ res = await githubDataClient(filePath)
+ } else {
+ res = await localDataClient(filePath)
+ }
+
+ return res.socials as SocialData[]
+}
diff --git a/src/features/contact/index.ts b/src/features/contact/index.ts
index 9ea5382..90bd355 100644
--- a/src/features/contact/index.ts
+++ b/src/features/contact/index.ts
@@ -1,8 +1,4 @@
-import jsonData from './data.json'
-
-export * from './components/contact-item'
-export * from './components/contact-list'
-export * from './components/social'
-export * from './components/social-item'
-
-export { jsonData }
+export * from './contact-item'
+export * from './contact-list'
+export * from './social-list'
+export * from './social-item'
diff --git a/src/features/contact/components/social-item.tsx b/src/features/contact/social-item.tsx
similarity index 100%
rename from src/features/contact/components/social-item.tsx
rename to src/features/contact/social-item.tsx
diff --git a/src/features/contact/components/social.tsx b/src/features/contact/social-list.tsx
similarity index 68%
rename from src/features/contact/components/social.tsx
rename to src/features/contact/social-list.tsx
index 33c01ac..4573ba5 100644
--- a/src/features/contact/components/social.tsx
+++ b/src/features/contact/social-list.tsx
@@ -1,8 +1,8 @@
import * as React from 'react'
-import jsonData from '../data.json'
-import { SocialData, SocialItem } from './social-item'
+import { SocialItem } from './social-item'
+import * as contactService from './contact-service'
-const socials: SocialData[] = jsonData.socials as SocialData[]
+const socials = await contactService.getSocials()
export function SocialMediaList(): React.ReactElement {
return (
diff --git a/src/features/crafts/components/item.tsx b/src/features/crafts/craft-item.tsx
similarity index 100%
rename from src/features/crafts/components/item.tsx
rename to src/features/crafts/craft-item.tsx
diff --git a/src/features/crafts/components/list.tsx b/src/features/crafts/craft-list-section.tsx
similarity index 71%
rename from src/features/crafts/components/list.tsx
rename to src/features/crafts/craft-list-section.tsx
index 215babd..67dce40 100644
--- a/src/features/crafts/components/list.tsx
+++ b/src/features/crafts/craft-list-section.tsx
@@ -1,8 +1,8 @@
import * as React from 'react'
-import { CraftData, CraftItem } from './item'
-import jsonData from '../data.json'
+import { CraftItem } from './craft-item'
+import * as craftService from './craft-service'
-const crafts = jsonData.crafts as CraftData[]
+const crafts = await craftService.getCrafts()
export function CraftListSection(): React.ReactElement {
return (
diff --git a/src/features/crafts/craft-service.ts b/src/features/crafts/craft-service.ts
new file mode 100644
index 0000000..89b8b5f
--- /dev/null
+++ b/src/features/crafts/craft-service.ts
@@ -0,0 +1,19 @@
+'use server'
+
+import config from '@shared/libs/config'
+import type { CraftData } from './craft-item'
+import { githubDataClient, localDataClient } from '@shared/libs/connections'
+
+const filePath = '/crafts.json'
+const isProduction = config.isProduction
+
+export async function getCrafts(): Promise {
+ let res: any
+ if (isProduction) {
+ res = await githubDataClient(filePath)
+ } else {
+ res = await localDataClient(filePath)
+ }
+
+ return res.crafts as CraftData[]
+}
diff --git a/src/features/crafts/index.ts b/src/features/crafts/index.ts
index 1315eb0..027feab 100644
--- a/src/features/crafts/index.ts
+++ b/src/features/crafts/index.ts
@@ -1,6 +1,2 @@
-import jsonData from './data.json'
-
-export * from './components/item'
-export * from './components/list'
-
-export { jsonData }
+export * from './craft-item'
+export * from './craft-list-section'
diff --git a/src/features/faqs/components/ask-section.tsx b/src/features/faqs/ask-section.tsx
similarity index 100%
rename from src/features/faqs/components/ask-section.tsx
rename to src/features/faqs/ask-section.tsx
diff --git a/src/features/faqs/components/faq-item.tsx b/src/features/faqs/faq-item.tsx
similarity index 100%
rename from src/features/faqs/components/faq-item.tsx
rename to src/features/faqs/faq-item.tsx
diff --git a/src/features/faqs/components/list.tsx b/src/features/faqs/faq-list-section.tsx
similarity index 71%
rename from src/features/faqs/components/list.tsx
rename to src/features/faqs/faq-list-section.tsx
index b8b9ec7..8f22e42 100644
--- a/src/features/faqs/components/list.tsx
+++ b/src/features/faqs/faq-list-section.tsx
@@ -1,12 +1,11 @@
import * as React from 'react'
-import jsonData from '../data.json'
-
import { Accordion } from '@shared/components/ui/accordion'
-import { FAQData, FAQItem } from './faq-item'
+import { FAQItem } from './faq-item'
+import * as faqService from './faq-service'
-const faqs = jsonData.faqs as FAQData[]
+const faqs = await faqService.getFAQs()
-export function FAQListSection() {
+export function FAQListSection(): React.ReactElement {
return (
diff --git a/src/features/faqs/faq-service.ts b/src/features/faqs/faq-service.ts
new file mode 100644
index 0000000..4783cf8
--- /dev/null
+++ b/src/features/faqs/faq-service.ts
@@ -0,0 +1,19 @@
+'use server'
+
+import config from '@shared/libs/config'
+import { githubDataClient, localDataClient } from '@shared/libs/connections'
+import { FAQData } from './faq-item'
+
+const filePath = '/faqs.json'
+const isProduction = config.isProduction
+
+export async function getFAQs(): Promise {
+ let res: any
+ if (isProduction) {
+ res = await githubDataClient(filePath)
+ } else {
+ res = await localDataClient(filePath)
+ }
+
+ return res.faqs as FAQData[]
+}
diff --git a/src/features/faqs/index.ts b/src/features/faqs/index.ts
index e11128d..bb608b2 100644
--- a/src/features/faqs/index.ts
+++ b/src/features/faqs/index.ts
@@ -1,5 +1,3 @@
-import jsonData from './data.json'
-
-export * from './components/ask-section'
-export * from './components/faq-item'
-export * from './components/list'
+export * from './ask-section'
+export * from './faq-item'
+export * from './faq-list-section'
diff --git a/src/features/home/components/resource-item.tsx b/src/features/home/bio-item.tsx
similarity index 61%
rename from src/features/home/components/resource-item.tsx
rename to src/features/home/bio-item.tsx
index 54c81f0..99fa426 100644
--- a/src/features/home/components/resource-item.tsx
+++ b/src/features/home/bio-item.tsx
@@ -2,23 +2,34 @@ import * as React from 'react'
import Link from 'next/link'
import { mergeClass } from '@shared/utils/helper'
+export interface BioItemData {
+ type: string
+ url: string
+ label: string
+ className?: string
+}
+
interface LinkItemProps {
className?: string
children?: React.ReactNode
href: string
- target?: React.HTMLAttributeAnchorTarget
}
-export function LinkItem({
+interface BioItemProps {
+ data: BioItemData
+}
+
+function LinkItem({
href,
- target,
children,
className,
}: LinkItemProps): React.ReactElement {
+ const isUrl = href.includes('http://') || href.includes('https://')
+
return (
)
}
+
+export function BioItem({ data }: BioItemProps): React.ReactElement {
+ const { type, label, url, className } = data
+
+ const components = Object.freeze({
+ link: (
+
+ {label}
+
+ ),
+ })
+
+ return components[type]
+}
diff --git a/src/features/home/bio-section.tsx b/src/features/home/bio-section.tsx
new file mode 100644
index 0000000..aef38b6
--- /dev/null
+++ b/src/features/home/bio-section.tsx
@@ -0,0 +1,19 @@
+import * as React from 'react'
+import { BioItem } from './bio-item'
+import * as homeService from './home-service'
+
+const bios = await homeService.getBioLinks()
+
+export function BioSection(): React.ReactElement {
+ return (
+
+
+
+ {bios.map((data, index) => (
+
+ ))}
+
+
+
+ )
+}
diff --git a/src/features/home/components/resources.tsx b/src/features/home/components/resources.tsx
deleted file mode 100644
index 7e0cde4..0000000
--- a/src/features/home/components/resources.tsx
+++ /dev/null
@@ -1,63 +0,0 @@
-import * as React from 'react'
-import { LinkItem } from './resource-item'
-
-export function ResourcesSection(): React.ReactElement {
- return (
-
-
-
-
- Hire me
-
-
- Become partner (business)
-
-
- See my works
-
-
- Check my goodies
-
-
- My web design business (NEW)
-
-
- Suport me by donation
-
-
- Learn together with me
-
-
- My apps collection (NEW)
-
-
- See tiny dev resources (NEW)
-
-
- See all of my crafts
-
-
-
-
- )
-}
diff --git a/src/features/home/components/hero.tsx b/src/features/home/hero-section.tsx
similarity index 100%
rename from src/features/home/components/hero.tsx
rename to src/features/home/hero-section.tsx
diff --git a/src/features/home/home-service.tsx b/src/features/home/home-service.tsx
new file mode 100644
index 0000000..393eafa
--- /dev/null
+++ b/src/features/home/home-service.tsx
@@ -0,0 +1,19 @@
+'use server'
+
+import config from '@shared/libs/config'
+import { githubDataClient, localDataClient } from '@shared/libs/connections'
+import { BioItemData } from './bio-item'
+
+const filePath = '/bio.json'
+const isProduction = config.isProduction
+
+export async function getBioLinks(): Promise {
+ let res: any
+ if (isProduction) {
+ res = await githubDataClient(filePath)
+ } else {
+ res = await localDataClient(filePath)
+ }
+
+ return res.links as BioItemData[]
+}
diff --git a/src/features/home/index.ts b/src/features/home/index.ts
index 65d0f31..8fea0ab 100644
--- a/src/features/home/index.ts
+++ b/src/features/home/index.ts
@@ -1,3 +1,3 @@
-export * from './components/hero'
-export * from './components/resource-item'
-export * from './components/resources'
+export * from './hero-section'
+export * from './bio-item'
+export * from './bio-section'
diff --git a/src/features/journeys/components/experience-item.tsx b/src/features/journeys/experience-item.tsx
similarity index 100%
rename from src/features/journeys/components/experience-item.tsx
rename to src/features/journeys/experience-item.tsx
diff --git a/src/features/journeys/components/experience-section.tsx b/src/features/journeys/experience-section.tsx
similarity index 58%
rename from src/features/journeys/components/experience-section.tsx
rename to src/features/journeys/experience-section.tsx
index 04bf611..25cce7f 100644
--- a/src/features/journeys/components/experience-section.tsx
+++ b/src/features/journeys/experience-section.tsx
@@ -1,11 +1,10 @@
import * as React from 'react'
-import { ExperienceItem, ExperienceItemData } from './experience-item'
-import jsonData from '../data.json'
+import * as journeyService from './journey-service'
+import { ExperienceItem } from './experience-item'
-const experiences = jsonData.experiences as ExperienceItemData[]
-const sortedExperiences = [...experiences].reverse()
+const experiences = await journeyService.getExperiences()
-export function ExperienceSection() {
+export function ExperienceSection(): React.ReactElement {
return (
@@ -14,8 +13,8 @@ export function ExperienceSection() {