Skip to content

Commit

Permalink
Merge pull request #156 from github-community-projects/sutterj/org-se…
Browse files Browse the repository at this point in the history
…lection

feat: add org selection page
  • Loading branch information
sutterj committed Jun 7, 2024
2 parents 1b9e28a + 81afa4a commit f169912
Show file tree
Hide file tree
Showing 16 changed files with 415 additions and 107 deletions.
23 changes: 18 additions & 5 deletions src/app/[organizationId]/forks/[forkId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import Blankslate from '@primer/react/lib-esm/Blankslate/Blankslate'
import { DataTable, Table } from '@primer/react/lib-esm/DataTable'
import { Stack } from '@primer/react/lib-esm/Stack'
import { AppNotInstalledFlash } from 'app/components/flash/AppNotInstalledFlash'
import { MirrorSearch } from 'app/components/search/MirrorSearch'
import { SearchWithCreate } from 'app/components/search/SearchWithCreate'
import { useForkData } from 'hooks/useFork'
import { useOrgData } from 'hooks/useOrganization'
import { useCallback, useState } from 'react'
Expand All @@ -34,6 +34,7 @@ import { Loading } from 'app/components/loading/Loading'
import { ErrorFlash } from 'app/components/flash/ErrorFlash'
import { EditMirrorDialog } from 'app/components/dialog/EditMirrorDialog'
import Fuse from 'fuse.js'
import { ForkHeader } from 'app/components/header/ForkHeader'

const Fork = () => {
const { organizationId, forkId } = useParams()
Expand Down Expand Up @@ -125,13 +126,19 @@ const Fork = () => {
[setIsEditSuccessFlashOpen],
)

const closeAllFlashes = () => {
const closeAllFlashes = useCallback(() => {
closeCreateErrorFlash()
closeCreateSuccessFlash()
closeEditErrorFlash()
closeEditSuccessFlash()
closeDeleteErrorFlash()
}
}, [
closeCreateErrorFlash,
closeCreateSuccessFlash,
closeEditErrorFlash,
closeEditSuccessFlash,
closeDeleteErrorFlash,
])

// set search value to be empty string by default
const [searchValue, setSearchValue] = useState('')
Expand Down Expand Up @@ -282,8 +289,11 @@ const Fork = () => {
if (!mirrors || mirrorsLoading) {
return (
<Box>
<ForkHeader forkData={forkData} />
<ForkBreadcrumbs orgData={orgData} forkData={forkData} />
<MirrorSearch
<SearchWithCreate
placeholder="Find a mirror"
createButtonLabel="Create mirror"
searchValue={searchValue}
setSearchValue={setSearchValue}
openCreateDialog={openCreateDialog}
Expand Down Expand Up @@ -335,6 +345,7 @@ const Fork = () => {

return (
<Box>
<ForkHeader forkData={forkData} />
<Box sx={{ marginBottom: '10px' }}>
{!isLoading && !data?.installed && (
<AppNotInstalledFlash orgLogin={orgData?.login as string} />
Expand Down Expand Up @@ -401,7 +412,9 @@ const Fork = () => {
)}
</Box>
<ForkBreadcrumbs orgData={orgData} forkData={forkData} />
<MirrorSearch
<SearchWithCreate
placeholder="Find a mirror"
createButtonLabel="Create mirror"
searchValue={searchValue}
setSearchValue={setSearchValue}
openCreateDialog={openCreateDialog}
Expand Down
13 changes: 1 addition & 12 deletions src/app/[organizationId]/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,9 @@
'use client'

import { Box } from '@primer/react'
import { OrgHeader } from 'app/components/header/OrgHeader'
import { useOrgData } from 'hooks/useOrganization'

const DashLayout = ({ children }: { children: React.ReactNode }) => {
const orgData = useOrgData()

return (
<Box sx={{ margin: '10px 90px' }}>
<Box>
<OrgHeader orgData={orgData} />
</Box>
<Box>{children}</Box>
</Box>
)
return <Box>{children}</Box>
}

export default DashLayout
22 changes: 18 additions & 4 deletions src/app/[organizationId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ import { AppNotInstalledFlash } from 'app/components/flash/AppNotInstalledFlash'
import { useForksData } from 'hooks/useForks'
import { useOrgData } from 'hooks/useOrganization'
import { useState } from 'react'
import { ForkSearch } from 'app/components/search/ForkSearch'
import { Search } from 'app/components/search/Search'
import Fuse from 'fuse.js'
import { OrgHeader } from 'app/components/header/OrgHeader'
import { OrgBreadcrumbs } from 'app/components/breadcrumbs/OrgBreadcrumbs'

const Organization = () => {
const { organizationId } = useParams()
Expand All @@ -45,7 +47,13 @@ const Organization = () => {
if (!forksData) {
return (
<Box>
<ForkSearch searchValue={searchValue} setSearchValue={setSearchValue} />
<OrgHeader orgData={orgData} />
<OrgBreadcrumbs orgData={orgData} />
<Search
placeholder="Find a fork"
searchValue={searchValue}
setSearchValue={setSearchValue}
/>
<Table.Container>
<Table.Skeleton
columns={[
Expand Down Expand Up @@ -76,7 +84,7 @@ const Organization = () => {
)
}

let forks = forksData.nodes
const forks = forksData.nodes

// set up search
const fuse = new Fuse(forks, {
Expand All @@ -97,12 +105,18 @@ const Organization = () => {

return (
<Box>
<OrgHeader orgData={orgData} />
<Box sx={{ marginBottom: '10px' }}>
{!isLoading && !data?.installed && (
<AppNotInstalledFlash orgLogin={orgData?.login as string} />
)}
</Box>
<ForkSearch searchValue={searchValue} setSearchValue={setSearchValue} />
<OrgBreadcrumbs orgData={orgData} />
<Search
placeholder="Find a fork"
searchValue={searchValue}
setSearchValue={setSearchValue}
/>
{forksData.totalCount === 0 ? (
<Box
sx={{
Expand Down
17 changes: 16 additions & 1 deletion src/app/auth/login/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,34 @@

import { Box } from '@primer/react'
import { Login } from 'app/components/login/Login'
import { useOrgsData } from 'hooks/useOrganizations'
import { useSession } from 'next-auth/react'
import { useRouter } from 'next/navigation'
import { useEffect } from 'react'

const LoginPage = () => {
const session = useSession()
const orgsData = useOrgsData()

const router = useRouter()

useEffect(() => {
if (session.data?.user) {
// if orgs data is still loading, do nothing
if (orgsData.isLoading) {
return
}

// if user only has one org, go to that org's page
if (orgsData.data?.length === 1) {
router.push(`/${orgsData.data[0].login}`)
return
}

// otherwise go to home page
router.push('/')
}
}, [session, router])
}, [session.data?.user, orgsData.isLoading, orgsData.data, router])

return <Box>{!session.data?.user && <Login />}</Box>
}
Expand Down
61 changes: 16 additions & 45 deletions src/app/components/breadcrumbs/ForkBreadcrumbs.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Box, Breadcrumbs, Label, Link, Text } from '@primer/react'
import { Stack } from '@primer/react/lib-esm/Stack'
import { Box, Breadcrumbs } from '@primer/react'
import { ForkData } from 'hooks/useFork'
import { OrgData } from 'hooks/useOrganization'

Expand All @@ -12,54 +11,26 @@ export const ForkBreadcrumbs = ({
orgData,
forkData,
}: ForkBreadcrumbsProps) => {
if (!forkData) {
if (!orgData || !forkData) {
return null
}

return (
<Box sx={{ marginBottom: '10px' }}>
<Stack direction="vertical" justify="start" gap="none">
<Stack.Item grow={false}>
<Stack.Item>
<Breadcrumbs sx={{ display: 'inline-block', paddingRight: '10px' }}>
<Breadcrumbs.Item
href={`/${orgData?.login}`}
sx={{ fontSize: '2', fontWeight: 'bold' }}
>
All Forks
</Breadcrumbs.Item>
<Breadcrumbs.Item
selected
sx={{ fontSize: '2', fontWeight: 'bold' }}
>
{forkData?.name}
</Breadcrumbs.Item>
</Breadcrumbs>
<Label variant="secondary">
{forkData?.private ? 'Private' : 'Public'}
</Label>
</Stack.Item>
<Stack.Item>
<Text
sx={{
color: 'fg.muted',
fontSize: '0.75rem',
fontWeight: '600',
}}
>
Forked from{' '}
<Link
href={`https://github.com/${forkData?.parent?.owner.login}/${forkData?.parent?.name}`}
target="_blank"
rel="noreferrer noopener"
sx={{ color: 'fg.muted' }}
>
{forkData?.parent?.owner.login}/{forkData?.parent?.name}
</Link>
</Text>
</Stack.Item>
</Stack.Item>
</Stack>
<Breadcrumbs sx={{ display: 'inline-block', paddingRight: '10px' }}>
<Breadcrumbs.Item href="/" sx={{ fontSize: '2', fontWeight: 'bold' }}>
All organizations
</Breadcrumbs.Item>
<Breadcrumbs.Item
href={`/${orgData?.login}`}
sx={{ fontSize: '2', fontWeight: 'bold' }}
>
{orgData?.login}
</Breadcrumbs.Item>
<Breadcrumbs.Item selected sx={{ fontSize: '2', fontWeight: 'bold' }}>
{forkData?.name}
</Breadcrumbs.Item>
</Breadcrumbs>
</Box>
)
}
25 changes: 25 additions & 0 deletions src/app/components/breadcrumbs/OrgBreadcrumbs.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Box, Breadcrumbs } from '@primer/react'
import { OrgData } from 'hooks/useOrganization'

interface ForkBreadcrumbsProps {
orgData: OrgData
}

export const OrgBreadcrumbs = ({ orgData }: ForkBreadcrumbsProps) => {
if (!orgData) {
return null
}

return (
<Box sx={{ marginBottom: '10px' }}>
<Breadcrumbs sx={{ display: 'inline-block', paddingRight: '10px' }}>
<Breadcrumbs.Item href="/" sx={{ fontSize: '2', fontWeight: 'bold' }}>
All organizations
</Breadcrumbs.Item>
<Breadcrumbs.Item selected sx={{ fontSize: '2', fontWeight: 'bold' }}>
{orgData?.login}
</Breadcrumbs.Item>
</Breadcrumbs>
</Box>
)
}
72 changes: 72 additions & 0 deletions src/app/components/header/ForkHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { Avatar, Label, Link, Pagehead, Spinner, Text } from '@primer/react'
import { Stack } from '@primer/react/lib-esm/Stack'
import { ForkData } from 'hooks/useFork'

interface ForkHeaderProps {
forkData: ForkData
}

export const ForkHeader = ({ forkData }: ForkHeaderProps) => {
return (
<Pagehead>
{forkData ? (
<Stack direction="horizontal" align="center">
<Stack.Item>
<Avatar
src={
forkData.parent?.owner.avatar_url ?? forkData.owner.avatar_url
}
size={48}
/>
</Stack.Item>
<Stack.Item grow={false}>
<Stack.Item>
<Link
href={forkData.html_url}
target="_blank"
rel="noreferrer noopener"
sx={{
color: 'fg.default',
fontSize: '3',
fontWeight: 'bold',
paddingRight: '5px',
}}
>
{forkData.organization?.login}/{forkData.name}
</Link>
<Label variant="secondary">
{forkData.private ? 'Private' : 'Public'}
</Label>
</Stack.Item>
<Stack.Item>
<Text sx={{ color: 'fg.muted' }}>
Forked from{' '}
<Link
href={`https://github.com/${forkData.parent?.owner.login}/${forkData.parent?.name}`}
target="_blank"
rel="noreferrer noopener"
sx={{ color: 'fg.muted' }}
>
{forkData.parent?.owner.login}/{forkData.parent?.name}
</Link>
</Text>
</Stack.Item>
</Stack.Item>
</Stack>
) : (
<Stack align="center" direction="horizontal">
<Stack.Item>
<Spinner sx={{ marginTop: '5px' }} />
</Stack.Item>
<Stack.Item>
<Text
sx={{ color: 'fg.default', fontSize: '3', fontWeight: 'bold' }}
>
Loading fork data...
</Text>
</Stack.Item>
</Stack>
)}
</Pagehead>
)
}
20 changes: 20 additions & 0 deletions src/app/components/header/WelcomeHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { BugIcon, GitBranchIcon, RepoForkedIcon } from '@primer/octicons-react'
import { Avatar, Octicon, Pagehead, Text } from '@primer/react'
import { Stack } from '@primer/react/lib-esm/Stack'

export const WelcomeHeader = () => {
return (
<Pagehead>
<Stack align="center" direction="horizontal">
<Stack.Item>
<Octicon icon={RepoForkedIcon} size={48} />
</Stack.Item>
<Stack.Item>
<Text sx={{ color: 'fg.default', fontSize: '3', fontWeight: 'bold' }}>
Welcome to Internal Contribution Forks!
</Text>
</Stack.Item>
</Stack>
</Pagehead>
)
}
Loading

0 comments on commit f169912

Please sign in to comment.