[questions][feat] add homepage layout (#312)

* [questions][feat] add homepage layout

* [questions][fix] fix rebase errors

* [questions][fix] startAddOn for search bar

* [questions][feat] add nav bar

* [questions][chore]Remove margins

* [questions][feat] add filter section

* [questions][ui] change filter section alignment

* [questions][ui]Search bar in one row

* [questions][ui] Contribute questions dialog

* [questions][ui] wording changes

Co-authored-by: Jeff Sieu <jeffsy00@gmail.com>
pull/328/head
Ren Weilin 2 years ago committed by GitHub
parent 6c91ec2077
commit 827550a5fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,39 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 582.39 458.49">
<defs>
<style>
.cls-1{fill:#5252ee}.cls-2{fill:#7f7ff0}.cls-3{fill:#fff}.cls-4{fill:#363636}.cls-5{fill:#ff4585}.cls-6{fill:#00e5a0}
</style>
</defs>
<ellipse cx="291.19" cy="428.46" fill="#eef2f5" rx="291.19" ry="30.03"/>
<rect width="346.05" height="180.28" x="197.89" y="168.35" class="cls-1" rx="30" ry="30" transform="rotate(-90 370.92 258.49)"/>
<rect width="346.05" height="180.28" x="189.19" y="168.35" class="cls-2" rx="30" ry="30" transform="rotate(-90 362.22 258.49)"/>
<path d="M257.71 419.94V97.04h152.1a28.18 28.18 0 0128.18 28.18v266.54a28.18 28.18 0 01-28.18 28.18h-152.1z" class="cls-3"/>
<path d="M206.96 431.51v-346h151.11a29.17 29.17 0 0129.17 29.08v287.75a29.17 29.17 0 01-29.17 29.17H206.96z" class="cls-1"/>
<rect width="346.05" height="244.06" x="80.86" y="136.46" class="cls-2" rx="33.94" ry="33.94" transform="rotate(-90 253.89 258.49)"/>
<path fill="#ffcb2c" d="M131.87 397.57V119.41a33.94 33.94 0 0133.94-33.94h5.06v346h-5.07a33.94 33.94 0 01-33.93-33.9z"/>
<g opacity=".2">
<circle cx="148.62" cy="375.73" r="11.84"/>
<circle cx="148.62" cy="329.54" r="11.84"/>
<circle cx="148.62" cy="283.35" r="11.84"/>
<circle cx="148.62" cy="237.16" r="11.84"/>
<circle cx="148.62" cy="190.96" r="11.84"/>
<circle cx="148.62" cy="144.77" r="11.84"/>
</g>
<rect width="11.93" height="27.44" x="129.79" y="362.01" class="cls-4" rx="4.5" ry="4.5" transform="rotate(-90 135.755 375.735)"/>
<rect width="11.93" height="27.44" x="129.79" y="315.82" class="cls-4" rx="4.5" ry="4.5" transform="rotate(-90 135.75 329.54)"/>
<rect width="11.93" height="27.44" x="129.79" y="269.63" class="cls-4" rx="4.5" ry="4.5" transform="rotate(-90 135.75 283.35)"/>
<rect width="11.93" height="27.44" x="129.79" y="223.44" class="cls-4" rx="4.5" ry="4.5" transform="rotate(-90 135.75 237.16)"/>
<rect width="11.93" height="27.44" x="129.79" y="177.24" class="cls-4" rx="4.5" ry="4.5" transform="rotate(-90 135.755 190.965)"/>
<rect width="11.93" height="27.44" x="129.79" y="131.05" class="cls-4" rx="4.5" ry="4.5" transform="rotate(-90 135.75 144.77)"/>
<path d="M396.07 97.04h2.47v189.3h-2.47zm0 233.12h2.47v90.57h-2.47zm15.44-107.97h2.47v197.75h-2.47zm16.06 10.68h-2.47V101.54l2.47 1.79v129.54zm-2.47 58.71h2.47v45.59h-2.47zm-13.59-163h2.47v45.59h-2.47z" opacity=".1"/>
<path d="M237.95 271a5 5 0 01-3.54-1.46L211.9 247a5 5 0 010-7.07l22.51-22.51a5 5 0 017.07 7.07l-19 19 19 19a5 5 0 01-3.54 8.54zm64.82 0a5 5 0 01-3.54-8.54l19-19-19-19a5 5 0 017.07-7.07l22.51 22.51a5 5 0 010 7.07l-22.51 22.51a5 5 0 01-3.53 1.52zm-41.58 14.87a5 5 0 01-4.84-6.27l19.72-74.85a5 5 0 119.67 2.55L266 282.14a5 5 0 01-4.81 3.73z" class="cls-3"/>
<path fill="#ffe400" d="M92.72 186.5l5 13.1A2.32 2.32 0 0099 201l13.1 5a2.32 2.32 0 010 4.34l-13.1 5a2.32 2.32 0 00-1.35 1.35l-5 13.1a2.32 2.32 0 01-4.34 0l-5-13.1a2.32 2.32 0 00-1.35-1.35l-13.1-5a2.32 2.32 0 010-4.34l13.1-5a2.32 2.32 0 001.35-1.35l5-13.1a2.32 2.32 0 014.41-.05zm386.36 79.39l5.38 14.22a2.52 2.52 0 001.47 1.47l14.22 5.42a2.52 2.52 0 010 4.72l-14.22 5.38a2.52 2.52 0 00-1.47 1.47l-5.38 14.22a2.52 2.52 0 01-4.72 0L469 298.52a2.52 2.52 0 00-1.47-1.47l-14.22-5.38a2.52 2.52 0 010-4.72l14.22-5.38a2.52 2.52 0 001.47-1.47l5.38-14.22a2.52 2.52 0 014.7.01zM258.14 18l5.67 15a2.66 2.66 0 001.55 1.55l15 5.67a2.66 2.66 0 010 5l-15 5.67a2.66 2.66 0 00-1.55 1.55l-5.67 15a2.66 2.66 0 01-5 0l-5.67-15a2.66 2.66 0 00-1.55-1.55l-15-5.67a2.66 2.66 0 010-5l15-5.67a2.66 2.66 0 001.55-1.55l5.67-15a2.66 2.66 0 015 0zm-49.69 344.87l5.67 15a2.66 2.66 0 001.55 1.55l15 5.67a2.66 2.66 0 010 5l-15 5.67a2.66 2.66 0 00-1.55 1.55l-5.67 15a2.66 2.66 0 01-5 0l-5.67-15a2.66 2.66 0 00-1.55-1.55l-15-5.67a2.66 2.66 0 010-5l15-5.67a2.66 2.66 0 001.55-1.55l5.67-15a2.66 2.66 0 015 0z"/>
<rect width="90.16" height="59.5" x="480.14" y="173.05" class="cls-5" rx="11.44" ry="11.44" transform="rotate(30.42 525.27 202.83)"/>
<path d="M505.53 242.61a4.27 4.27 0 01-5.83-3.43l-1.49-11.87-1.1-8.77a4.27 4.27 0 016.4-4.21l10.94 6.42 10.94 6.42a4.27 4.27 0 01-.56 7.64l-8.19 3.31z" class="cls-5"/>
<circle cx="507.01" cy="194.63" r="5.78" class="cls-3" transform="rotate(-59.76 507.024 194.63)"/>
<circle cx="524.1" cy="204.6" r="5.78" class="cls-3" transform="rotate(-59.76 524.112 204.598)"/>
<circle cx="541.31" cy="214.63" r="5.78" class="cls-3" transform="rotate(-59.76 541.326 214.627)"/>
<rect width="86.2" height="56.89" x="69.02" y="11.6" class="cls-6" rx="10.94" ry="10.94" transform="rotate(-24.07 112.12 40.037)"/>
<path d="M132.16 77.47a4.08 4.08 0 01-5.9 2.64l-10.06-5.43-7.43-4a4.08 4.08 0 01.27-7.32l11.07-4.95 11.07-4.95a4.08 4.08 0 015.63 4.68l-2 8.21z" class="cls-6"/>
<path d="M115.94 53.34l-17.08-5.28 2.41-7.83 9.67 2.99 7.81-21.18 7.68 2.84-10.49 28.46z" class="cls-3"/>
</svg>

After

Width:  |  Height:  |  Size: 4.8 KiB

@ -0,0 +1,102 @@
import type { ComponentProps, ForwardedRef } from 'react';
import { useState } from 'react';
import { forwardRef } from 'react';
import type { UseFormRegisterReturn } from 'react-hook-form';
import { useForm } from 'react-hook-form';
import {
BuildingOffice2Icon,
CalendarDaysIcon,
QuestionMarkCircleIcon,
} from '@heroicons/react/24/outline';
import { Button, TextInput } from '@tih/ui';
import ContributeQuestionModal from './ContributeQuestionModal';
export type ContributeQuestionData = {
company: string;
date: Date;
questionContent: string;
questionType: string;
};
type TextInputProps = ComponentProps<typeof TextInput>;
type FormTextInputProps = Omit<TextInputProps, 'onChange'> &
Pick<UseFormRegisterReturn<never>, 'onChange'>;
function FormTextInputWithRef(
props: FormTextInputProps,
ref?: ForwardedRef<HTMLInputElement>,
) {
const { onChange, ...rest } = props;
return (
<TextInput
{...(rest as TextInputProps)}
ref={ref}
onChange={(_, event) => onChange(event)}
/>
);
}
const FormTextInput = forwardRef(FormTextInputWithRef);
export type ContributeQuestionCardProps = {
onSubmit: (data: ContributeQuestionData) => void;
};
export default function ContributeQuestionCard({
onSubmit,
}: ContributeQuestionCardProps) {
const { register, handleSubmit } = useForm<ContributeQuestionData>();
const [isOpen, setOpen] = useState<boolean>(false);
return (
<>
<form
className="flex flex-col items-stretch justify-center gap-2 rounded-md border border-slate-300 p-4"
onSubmit={handleSubmit(onSubmit)}>
<FormTextInput
isLabelHidden={true}
label="Question"
placeholder="Contribute a question"
{...register('questionContent')}
/>
<div className="flex items-end justify-center gap-x-2">
<div className="min-w-[150px] flex-1">
<FormTextInput
label="Company"
startAddOn={BuildingOffice2Icon}
startAddOnType="icon"
{...register('company')}
/>
</div>
<div className="min-w-[150px] flex-1">
<FormTextInput
label="Question type"
startAddOn={QuestionMarkCircleIcon}
startAddOnType="icon"
{...register('questionType')}
/>
</div>
<div className="min-w-[150px] flex-1">
<FormTextInput
label="Date"
startAddOn={CalendarDaysIcon}
startAddOnType="icon"
{...register('date')}
/>
</div>
<Button
label="Contribute"
type="submit"
variant="primary"
onClick={() => setOpen(true)}
/>
</div>
</form>
<ContributeQuestionModal
contributeState={isOpen}
setContributeState={setOpen}></ContributeQuestionModal>
</>
);
}

@ -0,0 +1,96 @@
import type { Dispatch, SetStateAction } from 'react';
import { Fragment, useState } from 'react';
import { Dialog, Transition } from '@headlessui/react';
import Checkbox from './ui-patch/Checkbox';
export type ContributeQuestionModalProps = {
contributeState: boolean;
setContributeState: Dispatch<SetStateAction<boolean>>;
};
export default function ContributeQuestionModal({
contributeState,
setContributeState,
}: ContributeQuestionModalProps) {
const [canSubmit, setCanSubmit] = useState<boolean>(false);
const handleCheckSimilarQuestions = (checked: boolean) => {
setCanSubmit(checked);
};
return (
<Transition.Root as={Fragment} show={contributeState}>
<Dialog
as="div"
className="relative z-10"
onClose={() => setContributeState(false)}>
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in duration-200"
leaveFrom="opacity-100"
leaveTo="opacity-0">
<div className="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" />
</Transition.Child>
<div className="fixed inset-0 z-10 overflow-y-auto">
<div className="flex min-h-full items-end justify-center p-4 text-center sm:items-center sm:p-0">
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
enterTo="opacity-100 translate-y-0 sm:scale-100"
leave="ease-in duration-200"
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95">
<Dialog.Panel className="relative transform overflow-hidden rounded-lg bg-white text-left shadow-xl transition-all sm:my-8 sm:w-full sm:max-w-2xl">
<div className="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
<div className="sm:flex sm:items-start">
<div className="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
<Dialog.Title
as="h3"
className="text-lg font-medium leading-6 text-gray-900">
Question Draft
</Dialog.Title>
<div className="mt-2">
<p className="text-sm text-gray-500">
Question Contribution form
</p>
</div>
</div>
</div>
</div>
<div className="bg-primary-50 px-4 py-3 sm:flex sm:flex-row sm:justify-between sm:px-6">
<div className="mb-1 flex">
<Checkbox
checked={canSubmit}
label="I have checked that my question is new"
onChange={handleCheckSimilarQuestions}></Checkbox>
</div>
<div className=" flex gap-x-2">
<button
className="inline-flex w-full justify-center rounded-md border border-gray-300 bg-white px-4 py-2 text-base font-medium text-gray-700 shadow-sm hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm"
type="button"
onClick={() => setContributeState(false)}>
Discard
</button>
<button
className="bg-primary-600 hover:bg-primary-700 focus:ring-primary-500 inline-flex w-full justify-center rounded-md border border-transparent px-4 py-2 text-base font-medium text-white shadow-sm focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:bg-gray-400 sm:ml-3 sm:w-auto sm:text-sm"
disabled={!canSubmit}
type="button"
onClick={() => setContributeState(false)}>
Contribute
</button>
</div>
</div>
</Dialog.Panel>
</Transition.Child>
</div>
</div>
</Dialog>
</Transition.Root>
);
}

@ -0,0 +1,56 @@
import Link from 'next/link';
const navigation = [
{ href: '/questions/landing', name: '*Landing*' },
{ href: '/questions', name: 'Home' },
{ href: '#', name: 'My Lists' },
{ href: '#', name: 'My Questions' },
{ href: '#', name: 'History' },
];
export default function NavBar() {
return (
<header className="bg-indigo-600">
<nav aria-label="Top" className="max-w-8xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex w-full items-center justify-between border-b border-indigo-500 py-3 lg:border-none">
<div className="flex items-center">
<a className="flex items-center" href="/questions">
<span className="sr-only">TIH Question Bank</span>
<img alt="TIH Logo" className="h-10 w-auto" src="/logo.svg" />
<span className="ml-4 font-bold text-white">
TIH Question Bank
</span>
</a>
<div className="ml-8 hidden space-x-6 lg:block">
{navigation.map((link) => (
<Link
key={link.name}
className="font-sm text-sm text-white hover:text-indigo-50"
href={link.href}>
{link.name}
</Link>
))}
</div>
</div>
<div className="ml-8 space-x-4">
<a
className="inline-block rounded-md border border-transparent bg-indigo-500 py-2 px-4 text-base font-medium text-white hover:bg-opacity-75"
href="#">
Sign in
</a>
</div>
</div>
<div className="flex flex-wrap justify-center space-x-6 py-4 lg:hidden">
{navigation.map((link) => (
<Link
key={link.name}
className="text-base font-medium text-white hover:text-indigo-50"
href={link.href}>
{link.name}
</Link>
))}
</div>
</nav>
</header>
);
}

@ -0,0 +1,72 @@
import {
ChatBubbleBottomCenterTextIcon,
ChevronDownIcon,
ChevronUpIcon,
EyeIcon,
} from '@heroicons/react/24/outline';
import { Badge, Button } from '@tih/ui';
export type QuestionOverviewCardProps = {
answerCount: number;
content: string;
location: string;
role: string;
similarCount: number;
timestamp: string;
upvoteCount: number;
};
export default function QuestionOverviewCard({
answerCount,
content,
similarCount,
upvoteCount,
timestamp,
role,
location,
}: QuestionOverviewCardProps) {
return (
<article className="flex gap-2 rounded-md border border-slate-300 p-4">
<div className="flex flex-col items-center">
<Button
icon={ChevronUpIcon}
isLabelHidden={true}
label="Upvote"
variant="tertiary"
/>
<p>{upvoteCount}</p>
<Button
icon={ChevronDownIcon}
isLabelHidden={true}
label="Downvote"
variant="tertiary"
/>
</div>
<div className="flex flex-col gap-2">
<div className="flex items-center gap-2 text-slate-500">
<Badge label="Technical" variant="primary" />
<p className="text-xs">
{timestamp} · {location} · {role}
</p>
</div>
<p className="line-clamp-2 text-ellipsis">{content}</p>
<div className="flex gap-2">
<Button
addonPosition="start"
icon={ChatBubbleBottomCenterTextIcon}
label={`${answerCount} answers`}
size="sm"
variant="tertiary"
/>
<Button
addonPosition="start"
icon={EyeIcon}
label={`${similarCount} received this`}
size="sm"
variant="tertiary"
/>
</div>
</div>
</article>
);
}

@ -0,0 +1,42 @@
import { MagnifyingGlassIcon } from '@heroicons/react/24/outline';
import { Select, TextInput } from '@tih/ui';
export type SortOption = {
label: string;
value: string;
};
export type QuestionSearchBarProps<SortOptions extends Array<SortOption>> = {
onSortChange?: (sortValue: SortOptions[number]['value']) => void;
sortOptions: SortOptions;
sortValue: SortOptions[number]['value'];
};
export default function QuestionSearchBar<
SortOptions extends Array<SortOption>,
>({
onSortChange,
sortOptions,
sortValue,
}: QuestionSearchBarProps<SortOptions>) {
return (
<div className="flex items-center gap-2">
<div className="flex-1 pt-1">
<TextInput
isLabelHidden={true}
label="Search by content"
placeholder="Search by content"
startAddOn={MagnifyingGlassIcon}
startAddOnType="icon"
/>
</div>
<span className="pl-3 pr-1 pt-1 text-sm">Sort by:</span>
<Select
display="inline"
label=""
options={sortOptions}
value={sortValue}
onChange={onSortChange}></Select>
</div>
);
}

@ -0,0 +1,62 @@
import { MagnifyingGlassIcon } from '@heroicons/react/24/outline';
import { Collapsible, TextInput } from '@tih/ui';
import Checkbox from '../ui-patch/Checkbox';
export type FilterOptions = {
checked: boolean;
label: string;
value: string;
};
export type FilterSectionProps = {
label: string;
onOptionChange: (optionValue: string, checked: boolean) => void;
options: Array<FilterOptions>;
} & (
| {
searchPlaceholder: string;
showAll?: never;
}
| {
searchPlaceholder?: never;
showAll: true;
}
);
export default function FilterSection({
label,
options,
searchPlaceholder,
showAll,
onOptionChange,
}: FilterSectionProps) {
return (
<div className="mx-2">
<Collapsible defaultOpen={true} label={label}>
<div className="-mx-2 flex flex-col items-stretch gap-2">
{!showAll && (
<TextInput
isLabelHidden={true}
label={label}
placeholder={searchPlaceholder}
startAddOn={MagnifyingGlassIcon}
startAddOnType="icon"
/>
)}
<div className="mx-1">
{options.map((option) => (
<Checkbox
key={option.value}
{...option}
onChange={(checked) => {
onOptionChange(option.value, checked);
}}
/>
))}
</div>
</div>
</Collapsible>
</div>
);
}

@ -0,0 +1,25 @@
import { useId } from 'react';
export type CheckboxProps = {
checked: boolean;
label: string;
onChange: (checked: boolean) => void;
};
export default function Checkbox({ label, checked, onChange }: CheckboxProps) {
const id = useId();
return (
<div className="flex items-center">
<input
checked={checked}
className="text-primary-600 focus:ring-primary-500 h-4 w-4 rounded border-gray-300"
id={id}
type="checkbox"
onChange={(event) => onChange(event.target.checked)}
/>
<label className="ml-3 min-w-0 flex-1 text-gray-700" htmlFor={id}>
{label}
</label>
</div>
);
}

@ -1,10 +1,202 @@
import QuestionBankTitle from '~/components/questions/QuestionBankTitle'; import { useMemo, useState } from 'react';
import ContributeQuestionCard from '~/components/questions/ContributeQuestionCard';
import type { FilterOptions } from '~/components/questions/filter/FilterSection';
import FilterSection from '~/components/questions/filter/FilterSection';
import NavBar from '~/components/questions/NavBar';
import QuestionOverviewCard from '~/components/questions/QuestionOverviewCard';
import QuestionSearchBar from '~/components/questions/QuestionSearchBar';
type FilterChoices = Array<Omit<FilterOptions, 'checked'>>;
const companies: FilterChoices = [
{
label: 'Google',
value: 'Google',
},
{
label: 'Meta',
value: 'meta',
},
];
// Code, design, behavioral
const questionTypes: FilterChoices = [
{
label: 'Code',
value: 'code',
},
{
label: 'Design',
value: 'design',
},
{
label: 'Behavioral',
value: 'behavioral',
},
];
const questionAges: FilterChoices = [
{
label: 'Last month',
value: 'last-month',
},
{
label: 'Last 6 months',
value: 'last-6-months',
},
{
label: 'Last year',
value: 'last-year',
},
];
const locations: FilterChoices = [
{
label: 'Singapore',
value: 'singapore',
},
];
export default function QuestionsHomePage() { export default function QuestionsHomePage() {
const [selectedCompanies, setSelectedCompanies] = useState<Array<string>>([]);
const [selectedQuestionTypes, setSelectedQuestionTypes] = useState<
Array<string>
>([]);
const [selectedQuestionAges, setSelectedQuestionAges] = useState<
Array<string>
>([]);
const [selectedLocations, setSelectedLocations] = useState<Array<string>>([]);
const companyFilterOptions = useMemo(() => {
return companies.map((company) => ({
...company,
checked: selectedCompanies.includes(company.value),
}));
}, [selectedCompanies]);
const questionTypeFilterOptions = useMemo(() => {
return questionTypes.map((questionType) => ({
...questionType,
checked: selectedQuestionTypes.includes(questionType.value),
}));
}, [selectedQuestionTypes]);
const questionAgeFilterOptions = useMemo(() => {
return questionAges.map((questionAge) => ({
...questionAge,
checked: selectedQuestionAges.includes(questionAge.value),
}));
}, [selectedQuestionAges]);
const locationFilterOptions = useMemo(() => {
return locations.map((location) => ({
...location,
checked: selectedLocations.includes(location.value),
}));
}, [selectedLocations]);
return ( return (
<main className="flex-1 overflow-y-auto"> <main className="flex flex-1 flex-col items-stretch overflow-y-auto">
<div className="flex h-full items-center justify-center"> <div className="pb-4">
<QuestionBankTitle /> <NavBar></NavBar>
</div>
<div className="flex">
<section className="w-[300px] border-r px-4">
<h2 className="text-xl font-semibold">Filter by</h2>
<div className="divide-y divide-slate-200">
<FilterSection
label="Company"
options={companyFilterOptions}
searchPlaceholder="Add company filter"
onOptionChange={(optionValue, checked) => {
if (checked) {
setSelectedCompanies((prev) => [...prev, optionValue]);
} else {
setSelectedCompanies((prev) =>
prev.filter((company) => company !== optionValue),
);
}
}}
/>
<FilterSection
label="Question types"
options={questionTypeFilterOptions}
showAll={true}
onOptionChange={(optionValue, checked) => {
if (checked) {
setSelectedQuestionTypes((prev) => [...prev, optionValue]);
} else {
setSelectedQuestionTypes((prev) =>
prev.filter((questionType) => questionType !== optionValue),
);
}
}}
/>
<FilterSection
label="Question age"
options={questionAgeFilterOptions}
showAll={true}
onOptionChange={(optionValue, checked) => {
if (checked) {
setSelectedQuestionAges((prev) => [...prev, optionValue]);
} else {
setSelectedQuestionAges((prev) =>
prev.filter((questionAge) => questionAge !== optionValue),
);
}
}}
/>
<FilterSection
label="Location"
options={locationFilterOptions}
searchPlaceholder="Add location filter"
onOptionChange={(optionValue, checked) => {
if (checked) {
setSelectedLocations((prev) => [...prev, optionValue]);
} else {
setSelectedLocations((prev) =>
prev.filter((location) => location !== optionValue),
);
}
}}
/>
</div>
</section>
<div className="flex flex-1 justify-center">
<div className="flex max-w-3xl flex-1 gap-x-4">
<div className="flex flex-1 flex-col items-stretch justify-start gap-4">
<ContributeQuestionCard
onSubmit={(data) => {
// eslint-disable-next-line no-console
console.log(data);
}}
/>
<QuestionSearchBar
sortOptions={[
{
label: 'Most recent',
value: 'most-recent',
},
{
label: 'Most upvotes',
value: 'most-upvotes',
},
]}
sortValue="most-recent"
/>
<QuestionOverviewCard
answerCount={0}
content="Given an array of integers nums and an integer target, return indices of the two numbers such that they add up. Given an array of integers nums and an integer target, return indices of the two numbers such that they add up. Given an array of integers nums and"
location="Menlo Park, CA"
role="Senior Engineering Manager"
similarCount={0}
timestamp="Last month"
upvoteCount={0}
/>
</div>
</div>
</div>
</div> </div>
</main> </main>
); );

@ -23,7 +23,7 @@ export default function Collapsible({ children, defaultOpen, label }: Props) {
/> />
<span className="flex-1">{label}</span> <span className="flex-1">{label}</span>
</Disclosure.Button> </Disclosure.Button>
<Disclosure.Panel className="pt-1 pb-2 text-sm text-gray-500"> <Disclosure.Panel className="w-full pt-1 pb-2 text-sm text-gray-500">
{children} {children}
</Disclosure.Panel> </Disclosure.Panel>
</> </>

Loading…
Cancel
Save