Skip to content

Commit

Permalink
Merge pull request #581 from danactive/danactive/walk
Browse files Browse the repository at this point in the history
Admin Walk
  • Loading branch information
danactive committed Sep 6, 2023
2 parents 90e86fc + 9e92867 commit de5dac0
Show file tree
Hide file tree
Showing 14 changed files with 975 additions and 326 deletions.
1 change: 0 additions & 1 deletion next/jest.setup.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
// eslint-disable-next-line import/no-extraneous-dependencies
import '@testing-library/jest-dom'
3 changes: 3 additions & 0 deletions next/next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,8 @@ const nextConfig = {
images: {
domains: ['localhost', '127.0.0.1'],
},
eslint: {
dirs: ['pages', 'src', '__tests__'],
},
}
export default nextConfig
461 changes: 213 additions & 248 deletions next/package-lock.json

Large diffs are not rendered by default.

9 changes: 5 additions & 4 deletions next/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@
"@emotion/styled": "^11.11.0",
"@mui/joy": "^5.0.0-alpha.89",
"@types/react-image-gallery": "^1.2.0",
"@types/xml2js": "^0.4.11",
"@types/xml2js": "^0.4.12",
"boom": "^7.3.0",
"camelcase": "^6.3.0",
"color-thief-react": "^2.1.0",
"glob": "^10.3.3",
"glob": "^10.3.4",
"mapbox-gl": "^2.15.0",
"mime-types": "^2.1.35",
"next": "^13.4.19",
Expand All @@ -45,9 +45,10 @@
"@types/geojson": "^7946.0.10",
"@types/jest": "^29.5.4",
"@types/mime-types": "^2.1.1",
"@types/node": "^20.5.7",
"@types/node": "^20.5.9",
"@types/react": "^18.2.21",
"@types/react-dom": "^18.2.7",
"eslint": "^8.48.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-next": "^13.4.19",
"eslint-plugin-import": "^2.28.1",
Expand All @@ -60,7 +61,7 @@
"jest-environment-jsdom": "^29.6.4",
"jest-styled-components": "^7.1.1",
"next-test-api-route-handler": "^3.1.8",
"snyk": "^1.1207.0",
"snyk": "^1.1211.0",
"standard-version": "^9.5.0",
"ts-jest": "^29.1.1",
"typescript": "^5.2.2"
Expand Down
43 changes: 39 additions & 4 deletions next/pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { CssVarsProvider, extendTheme } from '@mui/joy/styles'
import { type AppProps } from 'next/app'
import { createGlobalStyle, ThemeProvider } from 'styled-components'
import { ThemeProvider, createGlobalStyle } from 'styled-components'

const GlobalStyle = createGlobalStyle`
body {
Expand All @@ -14,7 +15,39 @@ const GlobalStyle = createGlobalStyle`
}
`

const theme = {
const themeMui = extendTheme({
components: {
JoyListDivider: {
defaultProps: {
inset: 'gutter',
},
styleOverrides: {
root: {
backgroundColor: 'silver',
},
},
},
JoyList: {
styleOverrides: {
root: {
border: '1px solid silver',
borderRadius: '3px',
backgroundColor: '#545454',
color: 'red',
},
},
},
JoyListItem: {
styleOverrides: {
root: {
color: '#C0C0C0',
},
},
},
},
})

const themeStyled = {
colors: {
primary: '#0070f3',
},
Expand All @@ -24,8 +57,10 @@ export default function App({ Component, pageProps }: AppProps) {
return (
<>
<GlobalStyle />
<ThemeProvider theme={theme}>
<Component {...pageProps} />
<ThemeProvider theme={themeStyled}>
<CssVarsProvider theme={themeMui}>
<Component {...pageProps} />
</CssVarsProvider>
</ThemeProvider>
</>
)
Expand Down
61 changes: 61 additions & 0 deletions next/pages/admin/walk.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { List, ListDivider, ListItem } from '@mui/joy'
import { useRouter } from 'next/router'
import { Fragment, useEffect, useState } from 'react'

import ListFile from '../../src/components/Walk/ListFile'
import type { Filesystem, FilesystemBody } from '../../src/lib/filesystems'
import {
addParentDirectoryNav,
isImage,
organizeByMedia,
parseHash,
} from '../../src/utils/walk'

type ItemFile = Partial<Filesystem> & {
id: Filesystem['id'];
path: Filesystem['path'];
label: string;
grouped?: string;
flat?: string;
}

function WalkPage() {
const { asPath } = useRouter()
const [data, setData] = useState<FilesystemBody | null>(null)
const [isLoading, setLoading] = useState(false)
const pathQs = parseHash('path', asPath)

useEffect(() => {
setLoading(true)
fetch(`/api/admin/filesystems?path=${pathQs ?? '/'}`)
.then((response) => response.json())
.then((result: FilesystemBody) => {
setData(result)
setLoading(false)
})
}, [asPath])

if (isLoading) return <p>Loading...</p>
if (!data) return <p>No filesystem data</p>

const itemImages = data.files.filter((file) => isImage(file))
const hasImages = !isLoading && itemImages.length > 0
const fsItems = addParentDirectoryNav(organizeByMedia(data.files), pathQs)

return (
<>
<List>
{fsItems.map((item, i) => (
<Fragment key={item.id}>
{i > 0 && <ListDivider />}
<ListFile item={item} />
</Fragment>
))}
</List>
{hasImages && (<div>TODO display OrganizeThumbs</div>)}
</>
)
}

export { type ItemFile }
export default WalkPage
14 changes: 11 additions & 3 deletions next/pages/api/admin/filesystems/__tests__/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,20 @@ describe('Filesystem API', () => {
})
})

function matchFile(expect: jest.Expect, file: Filesystem) {
function matchPFile(expect: jest.Expect, file: Filesystem) {
expect(file.filename).toEqual('P1160066.JPG')
expect(file.ext).toEqual('JPG')
expect(file.mediumType).toEqual('image')
expect(file.name).toEqual('P1160066')
}

function matchJFile(expect: jest.Expect, file: Filesystem) {
expect(file.filename).toEqual('jay.js')
expect(file.ext).toEqual('js')
expect(file.mediumType).toEqual('application')
expect(file.name).toEqual('jay')
}

test('* GET fixtures has test files', async () => {
await testApiHandler({
handler,
Expand All @@ -42,7 +49,8 @@ describe('Filesystem API', () => {

expect(response.status).toBe(200)

matchFile(expect, result.files[2])
matchPFile(expect, result.files[1])
matchJFile(expect, result.files[0])
expect(result.files.length).toEqual(3)
},
params: { path: 'test/fixtures/walkable' },
Expand All @@ -58,7 +66,7 @@ describe('Filesystem API', () => {

expect(response.status).toBe(200)

matchFile(expect, result.files[0])
matchPFile(expect, result.files[0])
expect(result.files.length).toEqual(1)
},
params: { path: 'test/fixtures/walk%20able' },
Expand Down
62 changes: 15 additions & 47 deletions next/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { List, ListDivider, ListItem } from '@mui/joy'
import { CssVarsProvider } from '@mui/joy/styles'
import { type GetStaticProps } from 'next'
import Head from 'next/head'
import { Fragment } from 'react'
import styled from 'styled-components'

import Link from '../src/components/Link'
import getGalleries, { type Gallery } from '../src/lib/galleries'
Expand All @@ -22,16 +20,6 @@ export const getStaticProps: GetStaticProps<Props> = async () => {
}
}

const Wrapper = styled.div`
padding: 0;
margin: 0;
width: 100%;
background-color: #545454;
border: 1px solid #ccc;
border-radius: 3px;
overflow: hidden;
`

function Home({ galleries }: Props) {
return (
<>
Expand All @@ -40,41 +28,21 @@ function Home({ galleries }: Props) {
<link rel="icon" href="/favicon.ico" />
</Head>

<CssVarsProvider defaultMode="dark">
<main>
<h1>List of Galleries</h1>
<Wrapper>
<List
aria-labelledby="galleries"
variant="outlined"
sx={{
listStyle: 'none',
margin: 0,
padding: '0',
width: '100%',
maxHeight: '30em',
overflowY: 'auto',
}}
>
{galleries && galleries.map((item, i) => (
<Fragment key={`frag${item.gallery}`}>
{i > 0 && (
<ListDivider
sx={{ background: '#ccc' }}
inset="gutter"
/>
)}
<ListItem>
<Link href={`/${item.gallery}`}>
{item.gallery}
</Link>
</ListItem>
</Fragment>
))}
</List>
</Wrapper>
</main>
</CssVarsProvider>
<main>
<h1>List of Galleries</h1>
<List>
{galleries && galleries.map((item, i) => (
<Fragment key={`frag${item.gallery}`}>
{i > 0 && <ListDivider />}
<ListItem>
<Link href={`/${item.gallery}`}>
{item.gallery}
</Link>
</ListItem>
</Fragment>
))}
</List>
</main>
</>
)
}
Expand Down
20 changes: 11 additions & 9 deletions next/src/components/Link/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import NextLink from 'next/link'
import { memo, type ReactNode } from 'react'
import styled from 'styled-components'

const ColouredLink = styled.a`
const ColouredLink = styled(NextLink)`
color: #6cc0e5;
&:hover {
Expand All @@ -22,15 +22,17 @@ const ColouredLink = styled.a`
}
`

function Link({
children, href, title = '', ...props
}: {
children: ReactNode, href: string, title?: string,
}) {
interface InputGroupProps extends React.ComponentPropsWithoutRef<'a'> {
children: ReactNode;
href: string;
}

function Link(
{ children, ...props }:
InputGroupProps,
) {
return (
<NextLink href={href} {...props} passHref legacyBehavior>
<ColouredLink title={title}>{children}</ColouredLink>
</NextLink>
<ColouredLink {...props}>{children}</ColouredLink>
)
}

Expand Down
19 changes: 19 additions & 0 deletions next/src/components/Walk/ListFile.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { ListItem } from '@mui/joy'

import { type ItemFile } from '../../../pages/admin/walk'
import Link from '../Link'

function ListFile({ item: file }: { item: ItemFile }) {
if (file.mediumType === 'folder') {
const href = file.path ? `#path=${file.path}` : ''
return (
<ListItem>
<Link href={href}>{file.label}</Link>
</ListItem>
)
}

return <ListItem>{file.label}</ListItem>
}

export default ListFile
43 changes: 43 additions & 0 deletions next/src/components/Walk/__tests__/ListFile.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { render } from '@testing-library/react'

import ListFile from '../ListFile'
import { type ItemFile } from '../../../../pages/admin/walk'

describe('<ListFile />', () => {
const mockItemFile: ItemFile = {
id: '123',
label: 'One Two Three',
path: '123',
}
test('should render file label', () => {
const label = 'label'
const { getByText } = render(<ListFile item={{ ...mockItemFile, label }} />)
expect(getByText(label)).toBeInTheDocument()
})
test('should render a folder with path', () => {
const path = 'testPath'
const label = 'Link text'
const { getByText } = render(<ListFile
item={{
...mockItemFile,
mediumType: 'folder',
path,
label,
}}
/>)
expect(getByText(label).closest('a')?.href).toBe(`http://localhost/#path=${path}`)
})
test('should render a folder with path', () => {
const path = ''
const label = 'Link text'
const { getByText } = render(<ListFile
item={{
...mockItemFile,
mediumType: 'folder',
path,
label,
}}
/>)
expect(getByText(label).closest('a')?.href).toBe('http://localhost/')
})
})

1 comment on commit de5dac0

@vercel
Copy link

@vercel vercel bot commented on de5dac0 Sep 6, 2023

Choose a reason for hiding this comment

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

Successfully deployed to the following URLs:

history – ./

history-git-main-danactive.vercel.app
history-danactive.vercel.app
history.domaindesign.ca

Please sign in to comment.