This commit is contained in:
Matthias Kretschmann 2024-02-05 09:29:00 +00:00
parent a5cd4aebda
commit 934ed0fff5
Signed by: m
GPG Key ID: 606EEEF3C479A91F
24 changed files with 47 additions and 37 deletions

View File

@ -9,6 +9,9 @@
"^(react/(.*)$)|^(react$)",
"^(next/(.*)$)|^(next$)",
"<THIRD_PARTY_MODULES>",
"^(@/(.*)$)|^(@$)",
"^(@content/(.*)$)|^(@content$)",
"^(@generated/(.*)$)|^(@generated$)",
"^[./]"
],
"importOrderSeparation": false,

View File

@ -44,9 +44,10 @@ If you are looking for the former Gatsby-based app, it is archived in the [`gats
All displayed project content is powered by one YAML file where all the portfolio's projects are defined. The project description itself is transformed from Markdown written inside the YAML file into HTML on build time.
Next.js automatically creates pages from each item in that file utilizing the [`[slug]/page.tsx`](src/app/[slug]/page.tsx) template.
Next.js automatically creates pages from each item in that file utilizing the [`scripts/prebuild.ts`](scripts/prebuild.ts) script and the [`[slug]/page.tsx`](src/app/[slug]/page.tsx) template.
- [`_content/projects.yml`](_content/projects.yml)
- [`scripts/prebuild.ts`](scripts/prebuild.ts)
- [`src/app/[slug]/page.tsx`](src/app/[slug]/page.tsx)
### 🖼 Project images
@ -56,7 +57,7 @@ All project images live under `public/images` and are automatically attached to
Next.js with `next/image` generates all required image sizes for delivering responsible, responsive images to visitors, including lazy loading of all images. For this to work, images are analyzed on build time and various image metadata is passed down as props.
- [`src/components/ProjectImage/index.tsx`](src/components/ProjectImage/index.tsx)
- [`src/lib/content.ts`](src/lib/content.ts)
- [`script/content/images.ts`](script/content/images.ts)
### 🐱 GitHub repositories

View File

@ -1,4 +1,4 @@
import projects from '@/generated/projects.json'
import projects from '@generated/projects.json'
export function getAllSlugs() {
const slugs = projects.map(({ slug }: { slug: string }) => slug)

View File

@ -1,4 +1,4 @@
import projects from '@/generated/projects.json'
import projects from '@generated/projects.json'
export function getProjectBySlug(slug: string) {
return projects.find((item) => item.slug === slug)

View File

@ -1,10 +1,10 @@
import { Metadata } from 'next'
import { notFound } from 'next/navigation'
import meta from '@/_content/meta.json'
import projects from '@/generated/projects.json'
import Header from '@/src/components/Header/Header'
import Project from '@/src/components/Project'
import ProjectNav from '@/src/components/ProjectNav'
import Header from '@/components/Header/Header'
import Project from '@/components/Project'
import ProjectNav from '@/components/ProjectNav'
import meta from '@content/meta.json'
import projects from '@generated/projects.json'
import { getAllSlugs } from './getAllSlugs'
import { getProjectBySlug } from './getProjectBySlug'

View File

@ -1,4 +1,4 @@
import meta from '../../../_content/meta.json'
import meta from '@content/meta.json'
import styles from './index.module.css'
export default function Availability() {

View File

@ -1,4 +1,4 @@
import meta from '../../../_content/meta.json'
import meta from '@content/meta.json'
import LogoUnit from '../LogoUnit'
import Networks from '../Networks'
import Vcard from '../Vcard'

View File

@ -16,7 +16,7 @@ import {
Star,
Sun
} from 'lucide-react'
import Mastodon from '../../images/mastodon.svg'
import Mastodon from '@/images/mastodon.svg'
import styles from './index.module.css'
export default function Icon({ name, ...props }: { name: string }) {

View File

@ -1,9 +1,9 @@
'use client'
import { useEffect, useState } from 'react'
import { getLocation } from '@/src/app/actions'
import { useEffect, useState, useTransition } from 'react'
import RelativeTime from '@yaireo/relative-time'
import { LazyMotion, domAnimation, m, useReducedMotion } from 'framer-motion'
import { getLocation } from '@/app/actions'
import { fadeIn, getAnimationProps } from '../Transitions'
import { Flag } from './Flag'
import styles from './Location.module.css'
@ -11,22 +11,22 @@ import { UseLocation } from './types'
export default function Location() {
const shouldReduceMotion = useReducedMotion()
const [isPending, startTransition] = useTransition()
const [location, setLocation] = useState<UseLocation | null>(null)
const isDifferentCountry = location?.now?.country !== location?.next?.country
const relativeTime = new RelativeTime({ locale: 'en' })
useEffect(() => {
const updateLocation = async () => {
startTransition(async () => {
const location = await getLocation()
setLocation(location)
}
updateLocation()
})
}, [])
return (
<div className={styles.wrapper}>
{location?.now?.city ? (
{!isPending && location?.now?.city ? (
<LazyMotion features={domAnimation}>
<m.section
aria-label="Location"

View File

@ -1,6 +1,6 @@
import Link from 'next/link'
import meta from '../../../_content/meta.json'
import Logo from '../../images/logo.svg'
import Logo from '@/images/logo.svg'
import meta from '@content/meta.json'
import styles from './index.module.css'
type Props = {

View File

@ -1,7 +1,7 @@
'use client'
import { LazyMotion, domAnimation, m, useReducedMotion } from 'framer-motion'
import meta from '../../../_content/meta.json'
import meta from '@content/meta.json'
import { getAnimationProps } from '../Transitions'
import { NetworkLink } from './NetworkLink'
import styles from './index.module.css'

View File

@ -1,5 +1,5 @@
import Button from '../../Button'
import Icon from '../../Icon'
import Button from '@/components/Button'
import Icon from '@/components/Icon'
import styles from './index.module.css'
export default function ProjectLinks({

View File

@ -1,8 +1,8 @@
'use client'
import { LazyMotion, domAnimation, m, useReducedMotion } from 'framer-motion'
import type ImageType from '../../types/image'
import type ProjectType from '../../types/project'
import type ImageType from '@/types/image'
import type ProjectType from '@/types/project'
import ProjectImage from '../ProjectImage'
import { getAnimationProps, moveInBottom } from '../Transitions'
import ProjectLinks from './Links'

View File

@ -1,5 +1,5 @@
import Image from 'next/image'
import ImageType from '../../types/image'
import ImageType from '@/types/image'
import styles from './index.module.css'
export default function ProjectImage({

View File

@ -1,7 +1,7 @@
'use client'
import { createRef, useEffect } from 'react'
import ProjectType from '../../types/project'
import ProjectType from '@/types/project'
import { Project } from './Project'
import styles from './index.module.css'

View File

@ -1,4 +1,4 @@
import ProjectType from '../../types/project'
import ProjectType from '@/types/project'
import ProjectPreview from '../ProjectPreview'
import styles from './index.module.css'

View File

@ -1,7 +1,7 @@
import { render } from '@testing-library/react'
import Repo from '@/types/repo'
import Repositories from '.'
import repos from '../../../tests/__fixtures__/repos.json'
import Repo from '../../types/repo'
describe('Repositories', () => {
it('renders correctly', () => {

View File

@ -1,4 +1,4 @@
import Repo from '../../types/repo'
import Repo from '@/types/repo'
import Repository from '../Repository'
import styles from './index.module.css'

View File

@ -1,6 +1,6 @@
import { render } from '@testing-library/react'
import Repo from '@/types/repo'
import repos from '../../../tests/__fixtures__/repos.json'
import Repo from '../../types/repo'
import Repository from '../Repository'
describe('Repository', () => {

View File

@ -1,4 +1,4 @@
import Repo from '../../types/repo'
import Repo from '@/types/repo'
import Icon from '../Icon'
import styles from './index.module.css'

View File

@ -1,7 +1,7 @@
'use client'
import { MouseEvent } from 'react'
import meta from '../../../_content/meta.json'
import meta from '@content/meta.json'
export default function Vcard() {
const { name, label, email } = meta.author

View File

@ -1,5 +1,5 @@
import data from '../../_content/repos.json'
import Repo from '../types/repo'
import type Repo from '@/types/repo'
import filter from '@content/repos.json'
//
// Get GitHub repos
@ -18,7 +18,7 @@ const gitHubConfig = {
export async function getGithubRepos() {
let repos: Repo[] = []
for (let item of data) {
for (let item of filter) {
const user = item.split('/')[0]
const repoName = item.split('/')[1]
const data = await fetch(

View File

@ -16,6 +16,8 @@ const customJestConfig: Config = {
testEnvironment: 'jsdom',
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/$1',
'^@content/(.*)$': '<rootDir>/_content/$1',
'^@generated/(.*)$': '<rootDir>/generated/$1',
'^.+\\.(svg)$': '<rootDir>/tests/__mocks__/svgr-mock.tsx'
},
collectCoverage: true,

View File

@ -15,7 +15,11 @@
"jsx": "preserve",
"incremental": true,
"plugins": [{ "name": "next" }],
"paths": { "@/*": ["./*"] }
"paths": {
"@/*": ["./src/*"],
"@content/*": ["./_content/*"],
"@generated/*": ["./generated/*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]