/* eslint-disable react-hooks/rules-of-hooks */ import { Key, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { Avatar, Box, Button, ButtonGroup, Container, Flex, Heading, Icon, IconButton, Input, Skeleton, Spacer, Stack, Table, TableContainer, Tbody, Td, Text, Th, Thead, Tooltip, Tr, useColorModeValue, useDisclosure, useToast } from '@chakra-ui/react'; import { Link } from '@chakra-ui/next-js'; import { MdMail, MdOutlineAddCircle, MdOutlineJoinRight } from 'react-icons/md'; import Head from 'next/head'; import { useRouter } from 'next/router'; import { useAuthContext } from '@/contexts/AuthContext'; import Layout from '@/layouts/PlatformLayout'; import CreateOrganizationDialog from '@/components/CreateOrganizationDialog'; import JoinOrganizationDialog from '@/components/JoinOrganizationDialog'; import UserInvitationsModal from '@/components/UserInvitationsModal'; import { Organization, OrganizationMember } from '@/types'; import moment from 'moment'; import { AiFillSetting } from 'react-icons/ai'; import { BiGrid, BiRefresh } from 'react-icons/bi'; import { BsListUl } from 'react-icons/bs'; const toRelativeTime = (date: string) => { return moment(new Date(date)).fromNow(); }; const toActualTime = (date: string) => { return moment(new Date(date)).format('MMMM Do YYYY, h:mm:ss a'); } function GridEntry({ key, organization }: { key: Key, organization?: Organization }) { return <> {/* icon */} {/* text */} {organization?.name || "Organization"} by{' '} {organization?.owner?.displayName} { toRelativeTime(organization?.updatedAt as string) } } function TableEntry({ key, organization, skeleton }: { key: number | string, organization?: Organization, skeleton?: boolean }) { const { push } = useRouter(); return <> {!skeleton ? organization?.name : "Organization Name"} Owned by {!skeleton ? {organization?.owner?.displayName} : "Organization Owner"} {!skeleton ? toRelativeTime(organization?.updatedAt) : "Last Updated"} {!skeleton && organization?.updatedBy && " by "} {!skeleton ? {organization?.updatedBy?.displayName} : "Organization Owner"} {!skeleton ? organization?.description : "Organization Description"} } export default function PlatformOrganizations() { const { user, currentUser } = useAuthContext(); const { push, query } = useRouter(); const toast = useToast(); const [queryLoading, setQueryLoading] = useState(true); const [organizationsLoading, setOrganizationsLoading] = useState(true); const [organizations, setOrganizations] = useState([]); const [filteredOrganizations, setFilteredOrganizations] = useState([]); const [initialInviteCodeValue, setInitialInviteCodeValue] = useState(null); const searchRef = useRef(null); const [view, setView] = useState<'list' | 'grid' | null>(null); // modal disclosure hooks const { isOpen: isCreateOrganizationModalOpen, onOpen: onCreateOrganizationModalOpen, onClose: onCreateOrganizationModalClose } = useDisclosure(); const { isOpen: isJoinOrganizationModalOpen, onOpen: onJoinOrganizationModalOpen, onClose: onJoinOrganizationModalClose } = useDisclosure(); const { isOpen: isViewInvitationsModalOpen, onOpen: onViewInvitationsModalOpen, onClose: onViewInvitationsModalClose } = useDisclosure(); const refreshData = useCallback(async () => { setOrganizationsLoading(true); const token = await user?.getIdToken().then((token: string) => token); await fetch('/api/v1/me/organizations', { method: 'GET', headers: { Authorization: `Bearer ${token}` } }).then((res) => { if (res.status !== 200) { throw new Error('Failed to fetch organizations.'); } res .json() .then((data) => { setTimeout(() => { setOrganizations(data.organizations); setOrganizationsLoading(false); }, 100); }) .catch((err) => { toast({ title: 'Error', description: err.message, status: 'error', duration: 5000, isClosable: true }); }); }).catch((err) => { toast({ title: 'There was an error fetching your organizations.', description: err.message, status: 'error', duration: 5000, isClosable: true }); }); }, [toast, user]); useEffect(() => { if (!user) return; refreshData(); }, [user, refreshData]); const joinOrganizationPrompt = useCallback(async (inviteCode: string) => { setQueryLoading(true); setInitialInviteCodeValue(inviteCode); setQueryLoading(false); onJoinOrganizationModalOpen(); }, [onJoinOrganizationModalOpen]); useEffect(() => { if (!query) return; if (query.invitation) { joinOrganizationPrompt(query.invitation as string); } else { setTimeout(() => { setQueryLoading(false); }, 100); } }, [query.invitation, joinOrganizationPrompt, query]); const filterOrganizations = useCallback((query: string) => { if (!query) { setFilteredOrganizations(organizations); return; } const filtered = organizations.filter((organization: Organization) => { return organization.name.toLowerCase().includes(query.toLowerCase()) || organization.owner?.displayName?.toLowerCase().includes(query.toLowerCase()); }); setFilteredOrganizations(filtered); }, [organizations]); const toRelativeTime = useMemo(() => (date: string) => { return moment(new Date(date)).fromNow(); }, []); useEffect(() => { // load view option from local storage const viewOption = localStorage.getItem('organizationView'); if (viewOption) { setView(viewOption as 'list' | 'grid'); } else { setView('list'); localStorage.setItem('organizationView', 'list'); } }, []); useEffect(() => { // cache view option in local storage if (!view) return; localStorage.setItem('organizationView', view); }, [view]); useEffect(() => { if (!organizations) return; setFilteredOrganizations(organizations); }, [organizations]); return ( <> Organizations - Amperra Wyre { push(`/organizations/${id}/settings`); }} /> {!queryLoading && ( { push(`/organizations/${id}/settings`); }} initialValue={initialInviteCodeValue || ''} /> )} Organizations { filterOrganizations(e.target.value); }} /> } onClick={refreshData} /> { setView('list') }} icon={} /> { setView('grid') }} icon={} /> { view === 'list' ? ( {/* display list of organizations */} { organizationsLoading ? ( Array.from({ length: 6 }).map((_, i) => ( )) ) : (filteredOrganizations.map((organization: Organization) => ( ))) }
Organization Actions
) : ( { organizationsLoading ? ( Array.from({ length: 6 }).map((_, i) => ( )) ) : ( filteredOrganizations.map((organization: Organization) => ( )) ) } )} { !organizationsLoading && filteredOrganizations.length === 0 && ( No Organizations Found Try adjusting your search query or create a new organization. ) }
); } PlatformOrganizations.getLayout = (page: any) => {page};