Skip to content

Commit

Permalink
✨ View organizations (#27)
Browse files Browse the repository at this point in the history
  • Loading branch information
alejsdev authored Apr 13, 2024
1 parent 025faba commit c27a684
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 22 deletions.
6 changes: 3 additions & 3 deletions frontend/src/components/Common/ActionsMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@ import {
useDisclosure,
} from "@chakra-ui/react"
import { BsThreeDotsVertical } from "react-icons/bs"

import { FaEdit, FaTrash } from "react-icons/fa"
import type { ItemPublic, UserPublic } from "../../client"

import type { ItemPublic, OrganizationPublic, UserPublic } from "../../client"
import EditUser from "../Admin/EditUser"
import EditItem from "../Items/EditItem"
import Delete from "./DeleteAlert"

interface ActionsMenuProps {
type: string
value: ItemPublic | UserPublic
value: ItemPublic | UserPublic | OrganizationPublic
disabled?: boolean
}

Expand Down
5 changes: 2 additions & 3 deletions frontend/src/components/Common/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ import {
Text,
useDisclosure,
} from "@chakra-ui/react"
import { FaSignOutAlt } from "react-icons/fa"
import { FiMenu } from "react-icons/fi"
import { FaHamburger, FaSignOutAlt } from "react-icons/fa"

import Logo from "../../assets/images/fastapi-logo.svg"
import useAuth from "../../hooks/useAuth"
Expand All @@ -31,7 +30,7 @@ const Sidebar = () => {
<>
{/* Mobile */}
<IconButton
icon={<FiMenu />}
icon={<FaHamburger />}
onClick={onOpen}
display={{ base: "flex", md: "none" }}
aria-label="Open Menu"
Expand Down
31 changes: 24 additions & 7 deletions frontend/src/components/Common/UserMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,27 @@ import {
MenuList,
Text,
} from "@chakra-ui/react"
import { useQueryClient } from "@tanstack/react-query"
import { useQuery, useQueryClient } from "@tanstack/react-query"
import { Link } from "@tanstack/react-router"
import { FaCog, FaPlus, FaSignOutAlt, FaUser, FaUsers } from "react-icons/fa"
import {
FaCog,
FaList,
FaPlus,
FaSignOutAlt,
FaUser,
FaUsers,
} from "react-icons/fa"

import type { UserPublic } from "../../client"
import { OrganizationsService, type UserPublic } from "../../client"
import useAuth from "../../hooks/useAuth"

const UserMenu = () => {
const queryClient = useQueryClient()
const currentUser = queryClient.getQueryData<UserPublic>(["currentUser"])
const { data: organizations } = useQuery({
queryKey: ["organizations"],
queryFn: () => OrganizationsService.readOrganizations({}),
})
const { logout } = useAuth()

const handleLogout = async () => {
Expand Down Expand Up @@ -51,11 +62,17 @@ const UserMenu = () => {
<Icon as={FaUser} />
{currentUser?.full_name}
</MenuItem>
<MenuItem as={Link} to="/" gap={2} py={2}>
<Icon as={FaUsers} />
FastAPI Labs
{organizations?.data.slice(0, 3).map((org) => (
<MenuItem key={org.id} gap={2} py={2}>
<Icon as={FaUsers} />
{org.name}
</MenuItem>
))}
<MenuItem as={Link} to="/organizations/all" gap={2} py={2}>
<Icon as={FaList} />
View all organizations
</MenuItem>
<MenuItem as={Link} to="/organization/new" gap={2} py={2}>
<MenuItem as={Link} to="/organizations/new" gap={2} py={2}>
<Icon as={FaPlus} />
Create a new organization
</MenuItem>
Expand Down
23 changes: 17 additions & 6 deletions frontend/src/routeTree.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ import { Route as LayoutItemsImport } from './routes/_layout/items'
import { Route as LayoutHelpImport } from './routes/_layout/help'
import { Route as LayoutBillingImport } from './routes/_layout/billing'
import { Route as LayoutAdminImport } from './routes/_layout/admin'
import { Route as LayoutOrganizationNewImport } from './routes/_layout/organization/new'
import { Route as LayoutOrganizationsNewImport } from './routes/_layout/organizations/new'
import { Route as LayoutOrganizationsAllImport } from './routes/_layout/organizations/all'
import { Route as LayoutOrganizationInvitationsImport } from './routes/_layout/organization/invitations'

// Create/Update Routes
Expand Down Expand Up @@ -94,8 +95,13 @@ const LayoutAdminRoute = LayoutAdminImport.update({
getParentRoute: () => LayoutRoute,
} as any)

const LayoutOrganizationNewRoute = LayoutOrganizationNewImport.update({
path: '/organization/new',
const LayoutOrganizationsNewRoute = LayoutOrganizationsNewImport.update({
path: '/organizations/new',
getParentRoute: () => LayoutRoute,
} as any)

const LayoutOrganizationsAllRoute = LayoutOrganizationsAllImport.update({
path: '/organizations/all',
getParentRoute: () => LayoutRoute,
} as any)

Expand Down Expand Up @@ -165,8 +171,12 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof LayoutOrganizationInvitationsImport
parentRoute: typeof LayoutImport
}
'/_layout/organization/new': {
preLoaderRoute: typeof LayoutOrganizationNewImport
'/_layout/organizations/all': {
preLoaderRoute: typeof LayoutOrganizationsAllImport
parentRoute: typeof LayoutImport
}
'/_layout/organizations/new': {
preLoaderRoute: typeof LayoutOrganizationsNewImport
parentRoute: typeof LayoutImport
}
}
Expand All @@ -185,7 +195,8 @@ export const routeTree = rootRoute.addChildren([
LayoutSettingsRoute,
LayoutIndexRoute,
LayoutOrganizationInvitationsRoute,
LayoutOrganizationNewRoute,
LayoutOrganizationsAllRoute,
LayoutOrganizationsNewRoute,
]),
LoginRoute,
RecoverPasswordRoute,
Expand Down
1 change: 0 additions & 1 deletion frontend/src/routes/_layout/admin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import {
} from "@chakra-ui/react"
import { useQuery, useQueryClient } from "@tanstack/react-query"
import { createFileRoute } from "@tanstack/react-router"

import { FaCheckCircle } from "react-icons/fa"
import { FaCircleXmark } from "react-icons/fa6"

Expand Down
78 changes: 78 additions & 0 deletions frontend/src/routes/_layout/organizations/all.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import {
Container,
Flex,
Heading,
Spinner,
Table,
TableContainer,
Tbody,
Td,
Th,
Thead,
Tr,
} from "@chakra-ui/react"
import { useQuery } from "@tanstack/react-query"
import { createFileRoute } from "@tanstack/react-router"

import { OrganizationsService } from "../../../client"
import ActionsMenu from "../../../components/Common/ActionsMenu"
import useCustomToast from "../../../hooks/useCustomToast"

export const Route = createFileRoute("/_layout/organizations/all")({
component: All,
})

function All() {
const showToast = useCustomToast()
const {
data: organizations,
isLoading,
isError,
error,
} = useQuery({
queryKey: ["organizations"],
queryFn: () => OrganizationsService.readOrganizations({}),
})

if (isError) {
const errDetail = (error as any).body?.detail
showToast("Something went wrong.", `${errDetail}`, "error")
}

return (
<>
{isLoading ? (
// TODO: Add skeleton
<Flex justify="center" align="center" height="100vh" width="full">
<Spinner size="xl" color="ui.main" />
</Flex>
) : (
<Container maxW="large" p={12}>
<Heading size="md" textAlign={{ base: "center", md: "left" }}>
All Organizations
</Heading>
<TableContainer py={6}>
<Table size={{ base: "sm", md: "md" }}>
<Thead>
<Tr>
<Th>Name</Th>
<Th>Actions</Th>
</Tr>
</Thead>
<Tbody>
{organizations?.data.map((org) => (
<Tr key={org.id}>
<Td>{org.name}</Td>
<Td>
<ActionsMenu type="Organization" value={org} />
</Td>
</Tr>
))}
</Tbody>
</Table>
</TableContainer>
</Container>
)}
</>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
Input,
} from "@chakra-ui/react"
import { useMutation, useQueryClient } from "@tanstack/react-query"
import { createFileRoute } from "@tanstack/react-router"
import { createFileRoute, useNavigate } from "@tanstack/react-router"
import { type SubmitHandler, useForm } from "react-hook-form"

import {
Expand All @@ -20,11 +20,12 @@ import {
import Plans from "../../../components/Billing/Plans"
import useCustomToast from "../../../hooks/useCustomToast"

export const Route = createFileRoute("/_layout/organization/new")({
export const Route = createFileRoute("/_layout/organizations/new")({
component: NewOrg,
})

function NewOrg() {
const navigate = useNavigate()
const queryClient = useQueryClient()
const showToast = useCustomToast()
const {
Expand All @@ -43,13 +44,15 @@ function NewOrg() {
onSuccess: () => {
showToast("Success!", "Organization created successfully.", "success")
reset()
navigate({ to: "/organizations/all" })
},
onError: (err: ApiError) => {
const errDetail = (err.body as any)?.detail
showToast("Something went wrong.", `${errDetail}`, "error")
},
onSettled: () => {
queryClient.invalidateQueries({ queryKey: ["users"] })
queryClient.invalidateQueries({ queryKey: ["organizations"] })
},
})

Expand Down

0 comments on commit c27a684

Please sign in to comment.