Skip to content

Commit

Permalink
Merge pull request #486 from gregrickaby/feature/next-app-dir-mantine-v7
Browse files Browse the repository at this point in the history
Feature/next app dir mantine v7
  • Loading branch information
gregrickaby committed Sep 20, 2023
2 parents 278fa12 + ddd43d5 commit 66e39e1
Show file tree
Hide file tree
Showing 42 changed files with 2,401 additions and 1,659 deletions.
3 changes: 3 additions & 0 deletions .stylelintrc.js
@@ -0,0 +1,3 @@
module.exports = {
extends: ['stylelint-config-standard']
}
21 changes: 21 additions & 0 deletions app/Page.module.css
@@ -0,0 +1,21 @@
.container {
margin: 0 auto;
padding: 0 20px;
max-width: 1200px;

& > * {
margin-bottom: 20px;
margin-top: 20px;
}
}

.search {
align-items: center;
display: flex;
gap: 10px;
margin-bottom: 20px;
}

.main {
min-height: 100vh;
}
25 changes: 15 additions & 10 deletions pages/api/preSearch.ts → app/api/preSearch/route.ts
@@ -1,9 +1,6 @@
import type {NextRequest} from 'next/server'
import siteConfig from '~/lib/config'
import config from '~/lib/config'

export const config = {
runtime: 'edge'
}
export const runtime = 'edge'

/**
* Popular Subreddit Reddit API.
Expand All @@ -12,12 +9,20 @@ export const config = {
* /api/preSearch?limit=5
*
* @see https://www.reddit.com/dev/api#GET_subreddits_{where}
* @see https://nextjs.org/docs/api-routes/edge-api-routes
* @see https://nextjs.org/docs/api-reference/edge-runtime
* @see https://nextjs.org/docs/app/building-your-application/routing/route-handlers
* @see https://nextjs.org/docs/pages/api-reference/edge
*/
export default async function search(req: NextRequest) {
export async function GET(request: Request) {
// Get query params from request.
const {searchParams} = new URL(request.url)

// Parse params.
const unsanitizedLimit = searchParams.get('limit') || ''

// Parse and sanitize query params from request.
const limit = req.nextUrl.searchParams.get('limit') || '5'
const limit = unsanitizedLimit
? encodeURIComponent(unsanitizedLimit)
: config.redditApi.preSearchLimit

try {
// Generate random device ID.
Expand All @@ -32,7 +37,7 @@ export default async function search(req: NextRequest) {
method: 'POST',
headers: {
'Content-Type': 'application/json charset=UTF-8',
'User-Agent': siteConfig.userAgent,
'User-Agent': config.userAgent,
Authorization: `Basic ${btoa(
`${process.env.REDDIT_CLIENT_ID}:${process.env.REDDIT_CLIENT_SECRET}`
)}`
Expand Down
45 changes: 29 additions & 16 deletions pages/api/reddit.ts → app/api/reddit/route.ts
@@ -1,11 +1,8 @@
import type {NextRequest} from 'next/server'
import siteConfig from '~/lib/config'
import config from '~/lib/config'
import {getMediumImage} from '~/lib/helpers'
import {Posts} from '~/lib/types'

export const config = {
runtime: 'edge'
}
export const runtime = 'edge'

interface RedditAPIResponse {
kind: string
Expand All @@ -31,18 +28,34 @@ interface RedditPost {
* @example
* /api/reddit?sub=itookapicture&sort=hot&limit=24&after=t3_9x9j4d
*
* @see https://nextjs.org/docs/api-routes/edge-api-routes
* @see https://nextjs.org/docs/api-reference/edge-runtime
* @see https://nextjs.org/docs/app/building-your-application/routing/route-handlers
* @see https://nextjs.org/docs/pages/api-reference/edge
*/
export default async function reddit(req: NextRequest) {
export async function GET(request: Request) {
// Get query params from request.
const {searchParams} = new URL(request.url)

// Parse params.
const unsanitizedParams = {
postLimit: searchParams.get('limit') || '',
sortBy: searchParams.get('sort') || '',
subReddit: searchParams.get('sub') || '',
lastPost: searchParams.get('after') || ''
}

// Parse and sanitize query params from request.
const lastPost = req.nextUrl.searchParams.get('after') || ''
const postLimit =
req.nextUrl.searchParams.get('limit') || siteConfig.redditApi.limit
const sortBy =
req.nextUrl.searchParams.get('sort') || siteConfig.redditApi.sort
const subReddit =
req.nextUrl.searchParams.get('sub') || siteConfig.redditApi.subReddit
const postLimit = unsanitizedParams.postLimit
? encodeURIComponent(unsanitizedParams.postLimit)
: config.redditApi.limit
const sortBy = unsanitizedParams.sortBy
? encodeURIComponent(unsanitizedParams.sortBy)
: config.redditApi.sort
const subReddit = unsanitizedParams.subReddit
? encodeURIComponent(unsanitizedParams.subReddit)
: config.redditApi.subReddit
const lastPost = unsanitizedParams.lastPost
? encodeURIComponent(unsanitizedParams.lastPost)
: ''

try {
// Generate random device ID.
Expand All @@ -57,7 +70,7 @@ export default async function reddit(req: NextRequest) {
method: 'POST',
headers: {
'Content-Type': 'application/json charset=UTF-8',
'User-Agent': siteConfig.userAgent,
'User-Agent': config.userAgent,
Authorization: `Basic ${btoa(
`${process.env.REDDIT_CLIENT_ID}:${process.env.REDDIT_CLIENT_SECRET}`
)}`
Expand Down
26 changes: 15 additions & 11 deletions pages/api/search.ts → app/api/search/route.ts
@@ -1,9 +1,6 @@
import type {NextRequest} from 'next/server'
import siteConfig from '~/lib/config'
import config from '~/lib/config'

export const config = {
runtime: 'edge'
}
export const runtime = 'edge'

/**
* Search Reddit API.
Expand All @@ -12,13 +9,20 @@ export const config = {
* /api/search?term=itookapicture
*
* @see https://www.reddit.com/dev/api#GET_api_subreddit_autocomplete_v2
* @see https://nextjs.org/docs/api-routes/edge-api-routes
* @see https://nextjs.org/docs/api-reference/edge-runtime
* @see https://nextjs.org/docs/app/building-your-application/routing/route-handlers
* @see https://nextjs.org/docs/pages/api-reference/edge
*/
export default async function search(req: NextRequest) {
export async function GET(request: Request) {
// Get query params from request.
const {searchParams} = new URL(request.url)

// Parse params.
const unsanitizedTerm = searchParams.get('term') || ''

// Parse and sanitize query params from request.
const term =
req.nextUrl.searchParams.get('term') || siteConfig.redditApi.subReddit
const term = unsanitizedTerm
? encodeURIComponent(unsanitizedTerm)
: config.redditApi.subReddit

try {
// Generate random device ID.
Expand All @@ -33,7 +37,7 @@ export default async function search(req: NextRequest) {
method: 'POST',
headers: {
'Content-Type': 'application/json charset=UTF-8',
'User-Agent': siteConfig.userAgent,
'User-Agent': config.userAgent,
Authorization: `Basic ${btoa(
`${process.env.REDDIT_CLIENT_ID}:${process.env.REDDIT_CLIENT_SECRET}`
)}`
Expand Down
6 changes: 6 additions & 0 deletions app/components/BackToTop.module.css
@@ -0,0 +1,6 @@
.backtotop {
bottom: 12px;
position: fixed;
right: 12px;
z-index: 100;
}
32 changes: 32 additions & 0 deletions app/components/BackToTop.tsx
@@ -0,0 +1,32 @@
'use client'

import {Affix, Button, rem, Transition} from '@mantine/core'
import {useWindowScroll} from '@mantine/hooks'
import {IconArrowUp} from '@tabler/icons-react'
import classes from '~/components/BackToTop.module.css'

/**
* Back To Top component.
*/
export default function BackToTop() {
const [scroll, scrollTo] = useWindowScroll()

return (
<div className={classes.backtotop}>
<Affix position={{bottom: rem(20), right: rem(20)}}>
<Transition transition="slide-up" mounted={scroll.y > 0}>
{(transitionStyles) => (
<Button
aria-label="scroll to top"
leftSection={<IconArrowUp size="1rem" />}
style={transitionStyles}
onClick={() => scrollTo({y: 0})}
>
Scroll to top
</Button>
)}
</Transition>
</Affix>
</div>
)
}
19 changes: 19 additions & 0 deletions app/components/Footer.module.css
@@ -0,0 +1,19 @@
.footer {
display: flex;
flex-direction: column;
font-family: monospace;
font-size: 0.875rem;
text-align: center;

p {
margin-bottom: 0;
}

a {
color: var(--mantine-color-anchor);

&:hover {
text-decoration: none;
}
}
}
25 changes: 1 addition & 24 deletions components/Footer.tsx → app/components/Footer.tsx
@@ -1,34 +1,11 @@
import {createStyles} from '@mantine/core'
import {IconBrandGithub} from '@tabler/icons-react'
import classes from '~/components/Footer.module.css'
import config from '~/lib/config'

const useStyles = createStyles((theme) => ({
footer: {
display: 'flex',
flexDirection: 'column',
fontFamily: theme.fontFamilyMonospace,
fontSize: theme.fontSizes.sm,
textAlign: 'center',

p: {
marginBottom: 0
},

a: {
color: theme.colorScheme === 'dark' ? theme.colors.dark[0] : theme.black,

'&:hover': {
textDecoration: 'none'
}
}
}
}))

/**
* Footer component.
*/
export default function Footer() {
const {classes} = useStyles()
return (
<footer className={classes.footer}>
<p>
Expand Down
21 changes: 21 additions & 0 deletions app/components/Header.module.css
@@ -0,0 +1,21 @@
.header {
align-items: center;
display: flex;
justify-content: center;
}

.title {
cursor: pointer;
}

.description {
border: 0;
clip: rect(0 0 0 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
white-space: nowrap;
width: 1px;
}
32 changes: 32 additions & 0 deletions app/components/Header.tsx
@@ -0,0 +1,32 @@
'use client'

import {Title} from '@mantine/core'
import classes from '~/components/Header.module.css'
import {useRedditContext} from '~/components/RedditProvider'
import config from '~/lib/config'

/**
* Header component.
*/
export default function Header() {
const {setSearchInput, setSubreddit} = useRedditContext()

/**
* Reset the search input and subreddit.
*/
function resetSearch() {
setSearchInput(config?.redditApi?.subReddit)
setSubreddit(config?.redditApi?.subReddit)
}

return (
<header className={classes.header}>
<Title className={classes.title} order={1} onClick={resetSearch}>
{config.siteName}
</Title>
<Title className={classes.description} order={2}>
{config.siteDescription}
</Title>
</header>
)
}
2 changes: 2 additions & 0 deletions components/HlsPlayer.tsx → app/components/HlsPlayer.tsx
@@ -1,3 +1,5 @@
'use client'

import Hls from 'hls.js'
import {LegacyRef, useEffect, useRef, VideoHTMLAttributes} from 'react'

Expand Down

1 comment on commit 66e39e1

@vercel
Copy link

@vercel vercel bot commented on 66e39e1 Sep 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.