[offers][feat] add admin page to navbar (#553)

* [offers][feat] add admin page to navbar

* [offers][chore] remove comments
pull/554/head
Zhang Ziqing 2 years ago committed by GitHub
parent 75d7132409
commit 8e53e8dd4d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -11,11 +11,14 @@ import { Button } from '@tih/ui';
import GlobalNavigation from '~/components/global/GlobalNavigation'; import GlobalNavigation from '~/components/global/GlobalNavigation';
import HomeNavigation from '~/components/global/HomeNavigation'; import HomeNavigation from '~/components/global/HomeNavigation';
import OffersNavigation, { import OffersNavigation, {
OffersNavigationAdmin,
OffersNavigationAuthenticated, OffersNavigationAuthenticated,
} from '~/components/offers/OffersNavigation'; } from '~/components/offers/OffersNavigation';
import QuestionsNavigation from '~/components/questions/QuestionsNavigation'; import QuestionsNavigation from '~/components/questions/QuestionsNavigation';
import ResumesNavigation from '~/components/resumes/ResumesNavigation'; import ResumesNavigation from '~/components/resumes/ResumesNavigation';
import { trpc } from '~/utils/trpc';
import GoogleAnalytics from './GoogleAnalytics'; import GoogleAnalytics from './GoogleAnalytics';
import MobileNavigation from './MobileNavigation'; import MobileNavigation from './MobileNavigation';
import type { ProductNavigationItems } from './ProductNavigation'; import type { ProductNavigationItems } from './ProductNavigation';
@ -131,7 +134,12 @@ export default function AppShell({ children }: Props) {
const [mobileMenuOpen, setMobileMenuOpen] = useState(false); const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
const router = useRouter(); const router = useRouter();
const { data: session } = useSession(); const { data: session } = useSession();
const { isLoading: isOffersAdminResultsLoading, data: isOffersAdmin } =
trpc.useQuery(['offers.admin.isAdmin'], {
onError: () => {
router.push('/offers');
},
});
const currentProductNavigation: Readonly<{ const currentProductNavigation: Readonly<{
googleAnalyticsMeasurementID: string; googleAnalyticsMeasurementID: string;
logo?: React.ReactNode; logo?: React.ReactNode;
@ -149,7 +157,9 @@ export default function AppShell({ children }: Props) {
if (session == null) { if (session == null) {
return OffersNavigation; return OffersNavigation;
} }
return OffersNavigationAuthenticated; return !isOffersAdminResultsLoading && isOffersAdmin
? OffersNavigationAdmin
: OffersNavigationAuthenticated;
} }
if (path.startsWith('/questions')) { if (path.startsWith('/questions')) {

@ -13,6 +13,14 @@ const navigationAuthenticated: ProductNavigationItems = [
{ href: '/offers/about', name: 'About' }, { href: '/offers/about', name: 'About' },
]; ];
const navigationAdmin: ProductNavigationItems = [
{ href: '/offers/submit', name: 'Analyze your offers' },
{ href: '/offers/dashboard', name: 'My dashboard' },
{ href: '/offers/features', name: 'Features' },
{ href: '/offers/about', name: 'About' },
{ href: '/offers/admin', name: 'Admin' },
];
const config = { const config = {
googleAnalyticsMeasurementID: 'G-34XRGLEVCF', googleAnalyticsMeasurementID: 'G-34XRGLEVCF',
logo: ( logo: (
@ -28,6 +36,11 @@ const config = {
titleHref: '/offers', titleHref: '/offers',
}; };
export const OffersNavigationAdmin = {
...config,
navigation: navigationAdmin,
};
export const OffersNavigationAuthenticated = { export const OffersNavigationAuthenticated = {
...config, ...config,
navigation: navigationAuthenticated, navigation: navigationAuthenticated,

@ -1,10 +1,10 @@
import clsx from 'clsx'; import clsx from 'clsx';
import type { OfferTableSortType } from '~/components/offers/admin_temp/types'; import type { OfferTableSortType } from '~/components/offers/admin/types';
import { import {
getOppositeSortOrder, getOppositeSortOrder,
OFFER_TABLE_SORT_ORDER, OFFER_TABLE_SORT_ORDER,
} from '~/components/offers/admin_temp/types'; } from '~/components/offers/admin/types';
export type OffersTableHeaderProps = Readonly<{ export type OffersTableHeaderProps = Readonly<{
header: string; header: string;

@ -4,20 +4,20 @@ import { JobType } from '@prisma/client';
import { DropdownMenu, Spinner, useToast } from '@tih/ui'; import { DropdownMenu, Spinner, useToast } from '@tih/ui';
import { useGoogleAnalytics } from '~/components/global/GoogleAnalytics'; import { useGoogleAnalytics } from '~/components/global/GoogleAnalytics';
import OffersRow from '~/components/offers/admin_temp//OffersRow'; import OffersHeader from '~/components/offers/admin/OffersHeader';
import OffersHeader from '~/components/offers/admin_temp/OffersHeader'; import OffersRow from '~/components/offers/admin/OffersRow';
import OffersTablePagination from '~/components/offers/admin_temp/OffersTablePagination'; import OffersTablePagination from '~/components/offers/admin/OffersTablePagination';
import type { import type {
OfferTableColumn, OfferTableColumn,
OfferTableSortType, OfferTableSortType,
} from '~/components/offers/admin_temp/types'; } from '~/components/offers/admin/types';
import { import {
FullTimeOfferTableColumns, FullTimeOfferTableColumns,
InternOfferTableColumns, InternOfferTableColumns,
OFFER_TABLE_SORT_ORDER, OFFER_TABLE_SORT_ORDER,
OfferTableYoeOptions, OfferTableYoeOptions,
YOE_CATEGORY_PARAM, YOE_CATEGORY_PARAM,
} from '~/components/offers/admin_temp/types'; } from '~/components/offers/admin/types';
import { getCurrencyForCountry } from '~/utils/offers/currency/CurrencyEnum'; import { getCurrencyForCountry } from '~/utils/offers/currency/CurrencyEnum';
import CurrencySelector from '~/utils/offers/currency/CurrencySelector'; import CurrencySelector from '~/utils/offers/currency/CurrencySelector';
@ -294,12 +294,11 @@ export default function OffersTable({
<Spinner display="block" size="lg" /> <Spinner display="block" size="lg" />
</div> </div>
)} )}
{(!isLoading && !offers) || {!isLoading && (!offers || offers.length === 0) && (
(offers.length === 0 && (
<div className="py-16 text-lg"> <div className="py-16 text-lg">
<div className="flex justify-center">No data yet 🥺</div> <div className="flex justify-center">No data yet 🥺</div>
</div> </div>
))} )}
</div> </div>
<OffersTablePagination <OffersTablePagination
endNumber={ endNumber={

@ -1,15 +1,13 @@
import crypto from 'crypto';
import type { GetServerSideProps, InferGetServerSidePropsType } from 'next'; import type { GetServerSideProps, InferGetServerSidePropsType } from 'next';
import Head from 'next/head'; import Head from 'next/head';
import Link from 'next/link'; import Link from 'next/link';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import { useSession } from 'next-auth/react';
import { useState } from 'react'; import { useState } from 'react';
import { MapPinIcon } from '@heroicons/react/24/outline'; import { MapPinIcon } from '@heroicons/react/24/outline';
import { Banner } from '@tih/ui'; import { Banner } from '@tih/ui';
import { useGoogleAnalytics } from '~/components/global/GoogleAnalytics'; import { useGoogleAnalytics } from '~/components/global/GoogleAnalytics';
import OffersTable from '~/components/offers/admin_temp/OffersTable'; import OffersTable from '~/components/offers/admin/OffersTable';
import CompaniesTypeahead from '~/components/shared/CompaniesTypeahead'; import CompaniesTypeahead from '~/components/shared/CompaniesTypeahead';
import Container from '~/components/shared/Container'; import Container from '~/components/shared/Container';
import CountriesTypeahead from '~/components/shared/CountriesTypeahead'; import CountriesTypeahead from '~/components/shared/CountriesTypeahead';
@ -18,6 +16,7 @@ import { getLabelForJobTitleType } from '~/components/shared/JobTitles';
import JobTitlesTypeahead from '~/components/shared/JobTitlesTypeahead'; import JobTitlesTypeahead from '~/components/shared/JobTitlesTypeahead';
import { useSearchParamSingle } from '~/utils/offers/useSearchParam'; import { useSearchParamSingle } from '~/utils/offers/useSearchParam';
import { trpc } from '~/utils/trpc';
export const getServerSideProps: GetServerSideProps = async ({ req }) => { export const getServerSideProps: GetServerSideProps = async ({ req }) => {
return { return {
@ -41,23 +40,16 @@ export default function OffersHomePage({
const [selectedJobTitleId, setSelectedJobTitleId] = const [selectedJobTitleId, setSelectedJobTitleId] =
useSearchParamSingle<JobTitleType | null>('jobTitleId'); useSearchParamSingle<JobTitleType | null>('jobTitleId');
const { data: session, status } = useSession(); const { isLoading, data: isAuthorized } = trpc.useQuery(
['offers.admin.isAdmin'],
const authoizedPeople = [ {
'8b4550989cb7fe9ea7649b5538178b8d19aba0f3e5944dbff0b8d0e2ffe3911f', onError: () => {
'0544d5d2be7815b5347dd2233c4d08a52120e52ac529f21b1a5c2005db3c42ab', router.push('/offers');
'9934698c65bc72876018350a02910acdb27b7974dc757a320057588b67c5422b', },
'5cd57c9d1cc00d1010c3548ea3941941c04d18f7cf50766cdec30b12630e69ac', },
];
const isAuthorized = authoizedPeople.includes(
crypto
.createHash('sha256')
.update(session?.user?.email ?? '')
.digest('hex'),
); );
if (!isAuthorized && status !== 'loading') { if (!isLoading && !isAuthorized) {
router.push('/offers'); router.push('/offers');
} }
return ( return (
Loading…
Cancel
Save