mirror of
https://github.com/yangshun/tech-interview-handbook.git
synced 2026-02-03 02:24:47 +08:00
[offers][feat] add admin page to navbar (#553)
* [offers][feat] add admin page to navbar * [offers][chore] remove comments
This commit is contained in:
@@ -11,11 +11,14 @@ import { Button } from '@tih/ui';
|
||||
import GlobalNavigation from '~/components/global/GlobalNavigation';
|
||||
import HomeNavigation from '~/components/global/HomeNavigation';
|
||||
import OffersNavigation, {
|
||||
OffersNavigationAdmin,
|
||||
OffersNavigationAuthenticated,
|
||||
} from '~/components/offers/OffersNavigation';
|
||||
import QuestionsNavigation from '~/components/questions/QuestionsNavigation';
|
||||
import ResumesNavigation from '~/components/resumes/ResumesNavigation';
|
||||
|
||||
import { trpc } from '~/utils/trpc';
|
||||
|
||||
import GoogleAnalytics from './GoogleAnalytics';
|
||||
import MobileNavigation from './MobileNavigation';
|
||||
import type { ProductNavigationItems } from './ProductNavigation';
|
||||
@@ -131,7 +134,12 @@ export default function AppShell({ children }: Props) {
|
||||
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
|
||||
const router = useRouter();
|
||||
const { data: session } = useSession();
|
||||
|
||||
const { isLoading: isOffersAdminResultsLoading, data: isOffersAdmin } =
|
||||
trpc.useQuery(['offers.admin.isAdmin'], {
|
||||
onError: () => {
|
||||
router.push('/offers');
|
||||
},
|
||||
});
|
||||
const currentProductNavigation: Readonly<{
|
||||
googleAnalyticsMeasurementID: string;
|
||||
logo?: React.ReactNode;
|
||||
@@ -149,7 +157,9 @@ export default function AppShell({ children }: Props) {
|
||||
if (session == null) {
|
||||
return OffersNavigation;
|
||||
}
|
||||
return OffersNavigationAuthenticated;
|
||||
return !isOffersAdminResultsLoading && isOffersAdmin
|
||||
? OffersNavigationAdmin
|
||||
: OffersNavigationAuthenticated;
|
||||
}
|
||||
|
||||
if (path.startsWith('/questions')) {
|
||||
|
||||
@@ -13,6 +13,14 @@ const navigationAuthenticated: ProductNavigationItems = [
|
||||
{ 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 = {
|
||||
googleAnalyticsMeasurementID: 'G-34XRGLEVCF',
|
||||
logo: (
|
||||
@@ -28,6 +36,11 @@ const config = {
|
||||
titleHref: '/offers',
|
||||
};
|
||||
|
||||
export const OffersNavigationAdmin = {
|
||||
...config,
|
||||
navigation: navigationAdmin,
|
||||
};
|
||||
|
||||
export const OffersNavigationAuthenticated = {
|
||||
...config,
|
||||
navigation: navigationAuthenticated,
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import clsx from 'clsx';
|
||||
|
||||
import type { OfferTableSortType } from '~/components/offers/admin_temp/types';
|
||||
import type { OfferTableSortType } from '~/components/offers/admin/types';
|
||||
import {
|
||||
getOppositeSortOrder,
|
||||
OFFER_TABLE_SORT_ORDER,
|
||||
} from '~/components/offers/admin_temp/types';
|
||||
} from '~/components/offers/admin/types';
|
||||
|
||||
export type OffersTableHeaderProps = Readonly<{
|
||||
header: string;
|
||||
@@ -4,20 +4,20 @@ import { JobType } from '@prisma/client';
|
||||
import { DropdownMenu, Spinner, useToast } from '@tih/ui';
|
||||
|
||||
import { useGoogleAnalytics } from '~/components/global/GoogleAnalytics';
|
||||
import OffersRow from '~/components/offers/admin_temp//OffersRow';
|
||||
import OffersHeader from '~/components/offers/admin_temp/OffersHeader';
|
||||
import OffersTablePagination from '~/components/offers/admin_temp/OffersTablePagination';
|
||||
import OffersHeader from '~/components/offers/admin/OffersHeader';
|
||||
import OffersRow from '~/components/offers/admin/OffersRow';
|
||||
import OffersTablePagination from '~/components/offers/admin/OffersTablePagination';
|
||||
import type {
|
||||
OfferTableColumn,
|
||||
OfferTableSortType,
|
||||
} from '~/components/offers/admin_temp/types';
|
||||
} from '~/components/offers/admin/types';
|
||||
import {
|
||||
FullTimeOfferTableColumns,
|
||||
InternOfferTableColumns,
|
||||
OFFER_TABLE_SORT_ORDER,
|
||||
OfferTableYoeOptions,
|
||||
YOE_CATEGORY_PARAM,
|
||||
} from '~/components/offers/admin_temp/types';
|
||||
} from '~/components/offers/admin/types';
|
||||
|
||||
import { getCurrencyForCountry } from '~/utils/offers/currency/CurrencyEnum';
|
||||
import CurrencySelector from '~/utils/offers/currency/CurrencySelector';
|
||||
@@ -294,12 +294,11 @@ export default function OffersTable({
|
||||
<Spinner display="block" size="lg" />
|
||||
</div>
|
||||
)}
|
||||
{(!isLoading && !offers) ||
|
||||
(offers.length === 0 && (
|
||||
<div className="py-16 text-lg">
|
||||
<div className="flex justify-center">No data yet 🥺</div>
|
||||
</div>
|
||||
))}
|
||||
{!isLoading && (!offers || offers.length === 0) && (
|
||||
<div className="py-16 text-lg">
|
||||
<div className="flex justify-center">No data yet 🥺</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<OffersTablePagination
|
||||
endNumber={
|
||||
@@ -1,15 +1,13 @@
|
||||
import crypto from 'crypto';
|
||||
import type { GetServerSideProps, InferGetServerSidePropsType } from 'next';
|
||||
import Head from 'next/head';
|
||||
import Link from 'next/link';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useSession } from 'next-auth/react';
|
||||
import { useState } from 'react';
|
||||
import { MapPinIcon } from '@heroicons/react/24/outline';
|
||||
import { Banner } from '@tih/ui';
|
||||
|
||||
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 Container from '~/components/shared/Container';
|
||||
import CountriesTypeahead from '~/components/shared/CountriesTypeahead';
|
||||
@@ -18,6 +16,7 @@ import { getLabelForJobTitleType } from '~/components/shared/JobTitles';
|
||||
import JobTitlesTypeahead from '~/components/shared/JobTitlesTypeahead';
|
||||
|
||||
import { useSearchParamSingle } from '~/utils/offers/useSearchParam';
|
||||
import { trpc } from '~/utils/trpc';
|
||||
|
||||
export const getServerSideProps: GetServerSideProps = async ({ req }) => {
|
||||
return {
|
||||
@@ -41,23 +40,16 @@ export default function OffersHomePage({
|
||||
const [selectedJobTitleId, setSelectedJobTitleId] =
|
||||
useSearchParamSingle<JobTitleType | null>('jobTitleId');
|
||||
|
||||
const { data: session, status } = useSession();
|
||||
|
||||
const authoizedPeople = [
|
||||
'8b4550989cb7fe9ea7649b5538178b8d19aba0f3e5944dbff0b8d0e2ffe3911f',
|
||||
'0544d5d2be7815b5347dd2233c4d08a52120e52ac529f21b1a5c2005db3c42ab',
|
||||
'9934698c65bc72876018350a02910acdb27b7974dc757a320057588b67c5422b',
|
||||
'5cd57c9d1cc00d1010c3548ea3941941c04d18f7cf50766cdec30b12630e69ac',
|
||||
];
|
||||
|
||||
const isAuthorized = authoizedPeople.includes(
|
||||
crypto
|
||||
.createHash('sha256')
|
||||
.update(session?.user?.email ?? '')
|
||||
.digest('hex'),
|
||||
const { isLoading, data: isAuthorized } = trpc.useQuery(
|
||||
['offers.admin.isAdmin'],
|
||||
{
|
||||
onError: () => {
|
||||
router.push('/offers');
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (!isAuthorized && status !== 'loading') {
|
||||
if (!isLoading && !isAuthorized) {
|
||||
router.push('/offers');
|
||||
}
|
||||
return (
|
||||
Reference in New Issue
Block a user