Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert many examples to TypeScript #41825

Merged
merged 23 commits into from
Oct 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
040bd84
Convert `blog-with-comment` example to TypeScript
maxproske Oct 26, 2022
7a1dea4
Convert `custom-server` example to TypeScript
maxproske Oct 26, 2022
1c2ef53
Convert `environment-variables` example to TypeScript
maxproske Oct 26, 2022
b81950c
Convert `fast-refresh-demo` example to TypeScript
maxproske Oct 26, 2022
3c57819
Convert `github-pages` example to TypeScript
maxproske Oct 26, 2022
f4a4fdd
Convert `head-elements` example to TypeScript
maxproske Oct 26, 2022
aa05dc5
Convert `headers` example to TypeScript
maxproske Oct 26, 2022
96963b9
Convert `hello-world-esm` example to TypeScript
maxproske Oct 26, 2022
99b17e7
Convert `i18n-routing` example to TypeScript
maxproske Oct 26, 2022
da619c2
Convert `layout-component` example to TypeScript
maxproske Oct 26, 2022
f466eae
Convert `modularize-imports` example to TypeScript
maxproske Oct 26, 2022
e9aa9da
Convert `nested-components` example to TypeScript
maxproske Oct 26, 2022
ba919f1
Convert `progressive-render` example to TypeScript
maxproske Oct 26, 2022
2feed3b
Convert `react-remove-properties` example to TypeScript
maxproske Oct 26, 2022
2d7ddf6
Convert `redirects` example to TypeScript
maxproske Oct 26, 2022
28b864a
Convert `remove-console` example to TypeScript
maxproske Oct 26, 2022
dd66576
Convert `rewrites` example to TypeScript
maxproske Oct 26, 2022
74e2923
Convert `script-component` example to TypeScript
maxproske Oct 26, 2022
1aea92e
Convert `ssr-caching` example to TypeScript
maxproske Oct 26, 2022
e556901
Convert `styled-jsx-with-csp` example to TypeScript
maxproske Oct 26, 2022
eac2515
Convert `with-next-css` example to TypeScript
maxproske Oct 26, 2022
624ed28
Convert `with-next-offline` example to TypeScript
maxproske Oct 26, 2022
9789926
Merge branch 'canary' into convert-many-examples-typescript-v3
kodiakhq[bot] Oct 26, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions examples/blog-with-comment/.prettierrc

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
import { useAuth0 } from '@auth0/auth0-react'

function CommentForm({ text, setText, onSubmit }) {
type CommentFormProps = {
text: string
setText: Function
onSubmit: (e: React.FormEvent) => Promise<void>
}

export default function CommentForm({
text,
setText,
onSubmit,
}: CommentFormProps) {
const { isAuthenticated, logout, loginWithPopup } = useAuth0()

return (
<form onSubmit={onSubmit}>
<textarea
className="flex w-full max-h-40 p-3 rounded resize-y bg-gray-200 text-gray-900 placeholder-gray-500"
rows="2"
rows={2}
placeholder={
isAuthenticated
? `What are your thoughts?`
Expand Down Expand Up @@ -41,5 +51,3 @@ function CommentForm({ text, setText, onSubmit }) {
</form>
)
}

export default CommentForm
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import CommentForm from './form'
import CommentList from './list'
import useComments from '../../hooks/useComment'

function Comment() {
export default function Comment() {
const { text, setText, comments, onSubmit, onDelete } = useComments()

return (
Expand All @@ -12,5 +12,3 @@ function Comment() {
</div>
)
}

export default Comment
52 changes: 0 additions & 52 deletions examples/blog-with-comment/components/comment/list.js

This file was deleted.

57 changes: 57 additions & 0 deletions examples/blog-with-comment/components/comment/list.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import type { Comment } from '../../interfaces'
import distanceToNow from '../../lib/dateRelative'
import { useAuth0 } from '@auth0/auth0-react'

type CommentListProps = {
comments?: Comment[]
onDelete: (comment: Comment) => Promise<void>
}

export default function CommentList({ comments, onDelete }: CommentListProps) {
const { user } = useAuth0()

return (
<div className="space-y-6 mt-10">
{comments &&
comments.map((comment) => {
const isAuthor = user && user.sub === comment.user.sub
const isAdmin =
user && user.email === process.env.NEXT_PUBLIC_AUTH0_ADMIN_EMAIL

return (
<div key={comment.created_at} className="flex space-x-4">
<div className="flex-shrink-0">
<img
src={comment.user.picture}
alt={comment.user.name}
width={40}
height={40}
className="rounded-full"
/>
</div>

<div className="flex-grow">
<div className="flex space-x-2">
<b>{comment.user.name}</b>
<time className="text-gray-400">
{distanceToNow(comment.created_at)}
</time>
{(isAdmin || isAuthor) && (
<button
className="text-gray-400 hover:text-red-500"
onClick={() => onDelete(comment)}
aria-label="Close"
>
x
</button>
)}
</div>

<div>{comment.text}</div>
</div>
</div>
)
})}
</div>
)
}
5 changes: 0 additions & 5 deletions examples/blog-with-comment/components/container.js

This file was deleted.

7 changes: 7 additions & 0 deletions examples/blog-with-comment/components/container.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
type ContainerProps = {
children: React.ReactNode
}

export default function Container({ children }: ContainerProps) {
return <div className="container max-w-2xl m-auto px-4">{children}</div>
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,15 @@
import Link from 'next/link'
import Container from '../components/container'

function Header() {
export default function Header() {
return (
<header className="py-6">
<Container>
<nav className="flex space-x-4">
<Link href="/">
<a>About</a>
</Link>
<Link href="/posts">
<a>Posts</a>
</Link>
<Link href="/">About</Link>
<Link href="/posts">Posts</Link>
</nav>
</Container>
</header>
)
}

export default Header
8 changes: 8 additions & 0 deletions examples/blog-with-comment/environment.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
declare namespace NodeJS {
export interface ProcessEnv {
readonly NODE_ENV: 'development' | 'production' | 'test'
readonly NEXT_PUBLIC_AUTH0_DOMAIN: string
readonly NEXT_PUBLIC_AUTH0_CLIENT_ID: string
readonly NEXT_PUBLIC_BASE_URL: string
}
}
Original file line number Diff line number Diff line change
@@ -1,28 +1,32 @@
import { useState, useEffect } from 'react'
import type { Comment } from '../interfaces'
import React, { useState, useEffect } from 'react'
import useSWR from 'swr'
import { useAuth0 } from '@auth0/auth0-react'

async function fetcher(url: string) {
const query = new URLSearchParams({ url })
const queryUrl = `${url}?${query.toString()}`

return fetch(queryUrl).then((res) => res.json())
}

export default function useComments() {
const { getAccessTokenSilently } = useAuth0()
const [text, setText] = useState('')
const [url, setUrl] = useState(null)
const [url, setUrl] = useState<string | null>(null)

const { data: comments, mutate } = useSWR(
() => {
const query = new URLSearchParams({ url })
return `/api/comment?${query.toString()}`
},
{
initialData: [],
}
const { data: comments, mutate } = useSWR<Comment[]>(
'/api/comment',
fetcher,
{ fallbackData: [] }
)

useEffect(() => {
const url = window.location.origin + window.location.pathname
setUrl(url)
}, [])

const onSubmit = async (e) => {
const onSubmit = async (e: React.FormEvent) => {
e.preventDefault()
const token = await getAccessTokenSilently()

Expand All @@ -42,7 +46,7 @@ export default function useComments() {
}
}

const onDelete = async (comment) => {
const onDelete = async (comment: Comment) => {
const token = await getAccessTokenSilently()

try {
Expand Down
24 changes: 24 additions & 0 deletions examples/blog-with-comment/interfaces/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
export type User = {
name: string
picture: string
sub: string
email?: string
}

export type Comment = {
id: string
created_at: number
url: string
text: string
user: User
}

export type Post = {
slug?: string
title?: string
author?: string
date?: Date
content?: string
excerpt?: string
[key: string]: any
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,34 @@
import type { NextApiRequest, NextApiResponse } from 'next'
import type { Comment } from '../interfaces'
import redis from './redis'
import { nanoid } from 'nanoid'
import getUser from './getUser'

export default async function createComments(req, res) {
export default async function createComments(
req: NextApiRequest,
res: NextApiResponse
) {
const { url, text } = req.body
const { authorization } = req.headers

if (!url || !text || !authorization) {
return res.status(400).json({ message: 'Missing parameter.' })
}

if (!redis) {
return res
.status(400)
.json({ message: 'Failed to connect to redis client.' })
}

try {
// verify user token
const user = await getUser(authorization)
if (!user) return res.status(400).json({ message: 'Need authorization.' })

const { name, picture, sub, email } = user

const comment = {
const comment: Comment = {
id: nanoid(),
created_at: Date.now(),
url,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import formatDistanceToNowStrict from 'date-fns/formatDistanceToNowStrict'

export default function distanceToNow(dateTime) {
export default function distanceToNow(dateTime: number | Date) {
return formatDistanceToNowStrict(dateTime, {
addSuffix: true,
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
import type { NextApiRequest, NextApiResponse } from 'next'
import type { User, Comment } from '../interfaces'
import redis from './redis'
import getUser from './getUser'

export default async function deleteComments(req, res) {
const { url, comment } = req.body
export default async function deleteComments(
req: NextApiRequest,
res: NextApiResponse
) {
const { url, comment }: { url: string; comment: Comment } = req.body
const { authorization } = req.headers

if (!url || !comment || !authorization) {
return res.status(400).json({ message: 'Missing parameter.' })
}

if (!redis) {
return res.status(500).json({ message: 'Failed to connect to redis.' })
}

try {
// verify user token
const user = await getUser(authorization)
const user: User = await getUser(authorization)
if (!user) return res.status(400).json({ message: 'Invalid token.' })
comment.user.email = user.email

Expand All @@ -25,7 +34,7 @@ export default async function deleteComments(req, res) {
// delete
await redis.lrem(url, 0, JSON.stringify(comment))

return res.status(200).json()
return res.status(200).end()
} catch (err) {
return res.status(400)
}
Expand Down
Loading