actions refactor

This commit is contained in:
Matthias Kretschmann 2024-02-05 15:57:24 +00:00
parent c0da3a8311
commit c851e43f06
Signed by: m
GPG Key ID: 606EEEF3C479A91F
16 changed files with 85 additions and 101 deletions

26
package-lock.json generated
View File

@ -35,7 +35,6 @@
"eslint": "^8.56.0",
"eslint-config-next": "^14.1.0",
"jest": "^29.7.0",
"jest-canvas-mock": "^2.5.2",
"jest-environment-jsdom": "^29.7.0",
"js-yaml": "^4.1.0",
"ora": "^8.0.1",
@ -6323,12 +6322,6 @@
"node": ">=4"
}
},
"node_modules/cssfontparser": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/cssfontparser/-/cssfontparser-1.2.1.tgz",
"integrity": "sha512-6tun4LoZnj7VN6YeegOVb67KBX/7JJsqvj+pv3ZA7F878/eN33AbGa5b/S/wXxS/tcp8nc40xRUrsPlxIyNUPg==",
"dev": true
},
"node_modules/csso": {
"version": "5.0.5",
"resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz",
@ -8994,16 +8987,6 @@
}
}
},
"node_modules/jest-canvas-mock": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/jest-canvas-mock/-/jest-canvas-mock-2.5.2.tgz",
"integrity": "sha512-vgnpPupjOL6+L5oJXzxTxFrlGEIbHdZqFU+LFNdtLxZ3lRDCl17FlTMM7IatoRQkrcyOTMlDinjUguqmQ6bR2A==",
"dev": true,
"dependencies": {
"cssfontparser": "^1.2.1",
"moo-color": "^1.0.2"
}
},
"node_modules/jest-changed-files": {
"version": "29.7.0",
"resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz",
@ -11458,15 +11441,6 @@
"node": ">=16 || 14 >=14.17"
}
},
"node_modules/moo-color": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/moo-color/-/moo-color-1.0.3.tgz",
"integrity": "sha512-i/+ZKXMDf6aqYtBhuOcej71YSlbjT3wCO/4H1j8rPvxDJEifdwgg5MaFyu6iYAT8GBZJg2z0dkgK4YMzvURALQ==",
"dev": true,
"dependencies": {
"color-name": "^1.1.4"
}
},
"node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",

View File

@ -50,7 +50,6 @@
"eslint": "^8.56.0",
"eslint-config-next": "^14.1.0",
"jest": "^29.7.0",
"jest-canvas-mock": "^2.5.2",
"jest-environment-jsdom": "^29.7.0",
"js-yaml": "^4.1.0",
"ora": "^8.0.1",

View File

@ -0,0 +1,20 @@
'use server'
import { cache } from 'react'
export const preloadLocation = () => {
void getLocation()
}
export const getLocation = cache(async () => {
try {
const response = await fetch('https://location.kretschmann.io')
if (!response.ok)
throw new Error('Network response for location was not ok.')
const data = await response.json()
return data
} catch (error: unknown) {
console.error((error as Error).message)
}
})

View File

@ -0,0 +1,19 @@
'use server'
import { revalidatePath } from 'next/cache'
import { GiphyFetch } from '@giphy/js-fetch-api'
export async function getRandomGif(tag: string, pathname?: string) {
try {
// Famous last words:
// "It's just the 404 page so why not expose the dev API key"
const giphyClient = new GiphyFetch('LfXRwufRyt6PK414G2kKJBv3L8NdnxyR')
const { data } = await giphyClient.random({ tag })
const gif = data.images.original.mp4
return gif
} catch (error: unknown) {
console.error((error as Error).message)
}
if (pathname) revalidatePath(pathname)
}

13
src/actions/getRepos.ts Normal file
View File

@ -0,0 +1,13 @@
'use server'
import { cache } from 'react'
import { getGithubRepos } from '@/lib/github'
export const getRepos = cache(async () => {
try {
const repos = await getGithubRepos()
return repos
} catch (error: unknown) {
console.error((error as Error).message)
}
})

3
src/actions/index.ts Normal file
View File

@ -0,0 +1,3 @@
export * from './getRandomGif'
export * from './getRepos'
export * from './getLocation'

View File

@ -1,47 +0,0 @@
'use server'
import { cache } from 'react'
import { revalidatePath } from 'next/cache'
import { GiphyFetch } from '@giphy/js-fetch-api'
import { getGithubRepos } from '../lib/github'
export const preloadLocation = () => {
void getLocation()
}
export const getLocation = cache(async () => {
try {
const response = await fetch('https://location.kretschmann.io')
if (!response.ok)
throw new Error('Network response for location was not ok.')
const data = await response.json()
return data
} catch (error: unknown) {
console.error((error as Error).message)
}
})
export const getRepos = cache(async () => {
try {
const repos = await getGithubRepos()
return repos
} catch (error: unknown) {
console.error((error as Error).message)
}
})
export async function getRandomGif(tag: string, pathname?: string) {
try {
// Famous last words:
// "It's just the 404 page so why not expose the dev API key"
const giphyClient = new GiphyFetch('LfXRwufRyt6PK414G2kKJBv3L8NdnxyR')
const { data } = await giphyClient.random({ tag })
const gif = data.images.original.mp4
return gif
} catch (error: unknown) {
console.error((error as Error).message)
}
if (pathname) revalidatePath(pathname)
}

View File

@ -1,13 +1,13 @@
import { ReactNode } from 'react'
import { Metadata, Viewport } from 'next'
import Script from 'next/script'
import meta from '../../_content/meta.json'
import Footer from '../components/Footer'
import HostnameCheck from '../components/HostnameCheck'
import ThemeSwitch from '../components/ThemeSwitch'
import { UMAMI_SCRIPT_URL, UMAMI_WEBSITE_ID } from '../lib/umami'
import '../styles/global.css'
import styles from '../styles/layout.module.css'
import Footer from '@/components/Footer'
import HostnameCheck from '@/components/HostnameCheck'
import ThemeSwitch from '@/components/ThemeSwitch'
import { UMAMI_SCRIPT_URL, UMAMI_WEBSITE_ID } from '@/lib/umami'
import '@/styles/global.css'
import styles from '@/styles/layout.module.css'
import meta from '@content/meta.json'
import { Providers } from './providers'
const isProduction = process.env.NODE_ENV === 'production'

View File

@ -1,5 +1,5 @@
import { Metadata } from 'next'
import NotFound from '../components/404'
import NotFound from '@/components/404'
export const metadata: Metadata = {
title: `Shenanigans`,

View File

@ -1,9 +1,9 @@
import { Suspense } from 'react'
import projects from '../../generated/projects.json'
import Hero from '../components/Hero'
import Projects from '../components/Projects'
import Repositories from '../components/Repositories'
import { getRepos, preloadLocation } from './actions'
import { getRepos, preloadLocation } from '@/actions'
import Hero from '@/components/Hero'
import Projects from '@/components/Projects'
import Repositories from '@/components/Repositories'
import projects from '@generated/projects.json'
export default async function IndexPage() {
const repos = await getRepos()

View File

@ -1,9 +1,7 @@
import { fireEvent, render, screen } from '@testing-library/react'
import NotFoundPage from '../../../src/components/404'
import NotFoundPage from '@/components/404'
import mockData from '../../../tests/__fixtures__/giphy.json'
jest.setTimeout(30000)
describe('NotFoundPage', () => {
it('renders correctly', async () => {
render(<NotFoundPage />)

View File

@ -3,7 +3,7 @@
import { MouseEvent, useEffect, useState } from 'react'
import Link from 'next/link'
import { usePathname } from 'next/navigation'
import { getRandomGif } from '../../app/actions'
import { getRandomGif } from '@/actions/getRandomGif'
import Button from '../Button'
import styles from './index.module.css'

View File

@ -1,5 +1,5 @@
import Availability from '../Availability'
import { Location } from '../Location'
import Location from '../Location'
import LogoUnit from '../LogoUnit'
import Networks from '../Networks'
import styles from './Hero.module.css'

View File

@ -3,13 +3,13 @@
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 { getLocation } from '@/actions/getLocation'
import { fadeIn, getAnimationProps } from '../Transitions'
import { Flag } from './Flag'
import styles from './Location.module.css'
import { UseLocation } from './types'
export function Location() {
export default function Location() {
const shouldReduceMotion = useReducedMotion()
const [isPending, startTransition] = useTransition()
const [location, setLocation] = useState<UseLocation | null>(null)

View File

@ -1 +1 @@
export * from './Location'
export { default } from './Location'

View File

@ -1,7 +1,6 @@
import { jest } from '@jest/globals'
import '@testing-library/jest-dom'
import 'jest-canvas-mock'
import giphy from './__fixtures__/giphy.json'
import giphyMock from './__fixtures__/giphy.json'
import { dataLocation } from './__fixtures__/location'
import reposMock from './__fixtures__/repos.json'
import './__mocks__/matchMedia'
@ -10,13 +9,19 @@ jest.mock('next/navigation', () => ({
usePathname: jest.fn().mockImplementationOnce(() => '/')
}))
jest.mock('../src/app/actions', () => ({
jest.mock('../src/actions/getLocation', () => ({
getLocation: jest.fn().mockImplementation(() => dataLocation),
preloadLocation: jest.fn()
}))
jest.mock('../src/actions/getRandomGif', () => ({
getRandomGif: jest
.fn()
.mockImplementation(() => giphy.data.images.original.mp4),
preloadLocation: jest.fn(),
getRepos: jest.fn().mockImplementationOnce(() => reposMock)
.mockImplementation(() => giphyMock.data.images.original.mp4)
}))
jest.mock('../src/actions/getRepos', () => ({
getRepos: jest.fn().mockImplementation(() => reposMock)
}))
const unmockedFetch = global.fetch