Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix review 1 #7

Merged
merged 4 commits into from
Dec 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 12 additions & 19 deletions app/components/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ const tools = [
categories: ["Product Procurement", "Impact Measurements & Performance"],
},
]

interface EnAccessToolMapProps {
setIsModalOpen: (value: boolean) => void
}
Expand All @@ -114,8 +115,9 @@ const EnAccessToolMap = ({ setIsModalOpen }: EnAccessToolMapProps) => {

// Filter tools based on search term and selected categories
const filteredTools = useMemo(() => {
if (selectedCategories.length === 0 && !searchTerm) {
return tools
// Only show tools when categories are selected
if (selectedCategories.length === 0) {
return []
}

return tools.filter((tool) => {
Expand All @@ -132,14 +134,8 @@ const EnAccessToolMap = ({ setIsModalOpen }: EnAccessToolMapProps) => {
})
}, [searchTerm, selectedCategories])

// Flatten all menu items for easier selection

return (
<div className="bg-white text-gray-800">
{/* <header className="bg-[#2D6A4F] p-5 text-center text-white">
<Title level={1}>EnAccess Tool Map</Title>
</header> */}

<div className="flex justify-center my-5 gap-4">
<Input
placeholder="Search bar"
Expand All @@ -160,7 +156,11 @@ const EnAccessToolMap = ({ setIsModalOpen }: EnAccessToolMapProps) => {
{Object.entries(categories).map(([category, items]) => (
<Menu.SubMenu
key={category}
title={category}
title={
<span style={{ fontSize: "1.2em", margin: "0 0 10px 0" }}>
{category}
</span>
}
className={`bg-[#95D5B2] hover:bg-[#2D6A4F] hover:text-white`}
>
{items.map((item) => (
Expand Down Expand Up @@ -204,15 +204,6 @@ const EnAccessToolMap = ({ setIsModalOpen }: EnAccessToolMapProps) => {
)}
</div>

{/* <div className="text-center my-5">
<Title level={2}>Headliner & Digital Tool Map Graphic</Title>
<Paragraph>
Short description: Lorem ipsum dolor sit amet, consectetur adipiscing
elit, sed do eiusmod tempor incididunt ut labore et dolore magna
aliqua.
</Paragraph>
</div> */}

<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 p-5">
{filteredTools.length > 0 ? (
filteredTools.map((tool) => (
Expand Down Expand Up @@ -265,7 +256,9 @@ const EnAccessToolMap = ({ setIsModalOpen }: EnAccessToolMapProps) => {
<Empty
description={
<span className="text-gray-600">
No tools found for the selected categories
{selectedCategories.length === 0
? "Select a category to view tools"
: "No tools found for the selected categories"}
</span>
}
/>
Expand Down
256 changes: 144 additions & 112 deletions app/components/Questionairefilter.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
"use client"
import React, { useState, useMemo } from "react"
import { Input, Card, Typography, Collapse, Checkbox } from "antd"
import WelcomeMessage from "./WelcomeMessage"
import { Card, Typography, Button, Radio, Space } from "antd"

const { Title, Paragraph } = Typography
const { Panel } = Collapse

const QUESTIONNAIRE_ORDER = [
"numberOfClients",
"transactionsPerDay",
"companyStage",
"companyFocus",
"toolsCost",
"toolSource",
"internalExpertise",
"businessArea",
"functionalArea",
"interoperability",
"offlineFunctionality",
]
const filterKeyToQuestion: Record<string, string> = {
numberOfClients: " What Size is your company?",
companyStage: "At what phase/stage is your company?",
Expand Down Expand Up @@ -245,135 +256,156 @@ const tools = [
},
]

interface Filters {
numberOfClients: string[]
transactionsPerDay: string[]
companyStage: string[]
companyFocus: string[]
toolsCost: string[]
toolSource: string[]
internalExpertise: string[]
businessArea: string[]
functionalArea: string[]
interoperability: string[]
offlineFunctionality: string[]
}

const EnAccessToolMap: React.FC = () => {
const [filters, setFilters] = useState<Filters>({
numberOfClients: [],
transactionsPerDay: [],
companyStage: [],
companyFocus: [],
toolsCost: [],
toolSource: [],
internalExpertise: [],
businessArea: [],
functionalArea: [],
interoperability: [],
offlineFunctionality: [],
})
const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0)
const [answers, setAnswers] = useState<Record<string, string[]>>({})
const [isQuestionnaireComplete, setIsQuestionnaireComplete] = useState(false)

const [searchTerm, setSearchTerm] = useState<string>("")
const currentQuestion = QUESTIONNAIRE_ORDER[currentQuestionIndex]

const hasActiveFilters = Object.values(filters).some(
(filter) => filter.length > 0
)
const handleAnswer = (values: string[]) => {
setAnswers((prev) => ({
...prev,
[currentQuestion]: values,
}))
}

const handleNext = () => {
// If current question is not answered and not skipped, don't proceed
if (
!answers[currentQuestion] ||
(Array.isArray(answers[currentQuestion]) &&
!answers[currentQuestion].length)
) {
return
}

if (currentQuestionIndex < QUESTIONNAIRE_ORDER.length - 1) {
setCurrentQuestionIndex((prev) => prev + 1)
} else {
setIsQuestionnaireComplete(true)
}
}

const handleSkip = () => {
// Set an empty answer to allow skipping
setAnswers((prev) => ({
...prev,
[currentQuestion]: [],
}))

if (currentQuestionIndex < QUESTIONNAIRE_ORDER.length - 1) {
setCurrentQuestionIndex((prev) => prev + 1)
} else {
setIsQuestionnaireComplete(true)
}
}

const filteredTools = useMemo(() => {
if (!hasActiveFilters) return []
if (!isQuestionnaireComplete) return []

return tools.filter((tool) => {
return (
Object.entries(filters).every(([filterKey, selectedValues]) => {
if (selectedValues.length === 0) return true
return Object.entries(answers).every(([filterKey, selectedValues]) => {
// Skip filtering if no values were selected (skipped)
if (selectedValues.length === 0) return true

const metadataValue =
tool.metadata[filterKey as keyof typeof tool.metadata]
const metadataValue =
tool.metadata[filterKey as keyof typeof tool.metadata]

if (Array.isArray(metadataValue)) {
return selectedValues.some((value: string) =>
metadataValue.includes(value)
)
}
if (Array.isArray(metadataValue)) {
return selectedValues.some((value: string) =>
metadataValue.includes(value)
)
}

return selectedValues.includes(metadataValue)
}) && tool.name.toLowerCase().includes(searchTerm.toLowerCase())
)
return selectedValues.includes(metadataValue)
})
})
}, [filters, searchTerm, hasActiveFilters])
}, [answers, isQuestionnaireComplete])

const renderFilterSection = (filterKey: keyof Filters) => {
if (isQuestionnaireComplete) {
return (
<Panel
header={
filterKeyToQuestion[filterKey] ||
filterKey.replace(/([A-Z])/g, " $1").toUpperCase()
}
key={filterKey}
>
<Checkbox.Group
options={FILTER_OPTIONS[filterKey]}
value={filters[filterKey]}
onChange={(checkedValues: string[]) => {
setFilters((prev) => ({
...prev,
[filterKey]: checkedValues,
}))
<div className="p-8">
<Title level={2}>Recommended Tools</Title>
{filteredTools.length > 0 ? (
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
{filteredTools.map((tool) => (
<Card key={tool.name} className="bg-[#2D6A4F] text-white">
<Title level={3} className="text-white">
{tool.name}
</Title>
<Paragraph className="text-gray-100">{tool.summary}</Paragraph>

<a
href={tool.link}
target="_blank"
rel="noopener noreferrer"
className="text-blue-200 hover:text-blue-100"
>
Visit Website
</a>
</Card>
))}
</div>
) : (
<Paragraph>No tools match your criteria.</Paragraph>
)}
<Button
onClick={() => {
setIsQuestionnaireComplete(false)
setCurrentQuestionIndex(0)
setAnswers({})
}}
/>
</Panel>
className="mt-4"
>
Start Over
</Button>
</div>
)
}

return (
<div className="bg-white text-gray-800">
<div className="flex justify-center my-5">
<Input
placeholder="Search tools"
className="w-72"
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
/>
</div>
<div className="max-w-2xl mx-auto p-8">
<Title level={2}>Tool Finder </Title>
<Paragraph className="mb-6">
Question {currentQuestionIndex + 1} of {QUESTIONNAIRE_ORDER.length}
</Paragraph>

<div className="flex">
<div className="w-1/4 p-4">
<Collapse>
{Object.keys(FILTER_OPTIONS).map((filterKey) =>
renderFilterSection(filterKey as keyof Filters)
)}
</Collapse>
</div>
<Title level={3} className="mb-4">
{filterKeyToQuestion[currentQuestion]}
</Title>

<Radio.Group
onChange={(e) => handleAnswer([e.target.value])}
value={answers[currentQuestion]?.[0] || null}
className="w-full"
>
<Space direction="vertical" className="w-full">
{FILTER_OPTIONS[currentQuestion].map((option) => (
<Radio
key={option}
value={option}
className="w-full p-2 border rounded hover:bg-gray-100"
>
{option}
</Radio>
))}
</Space>
</Radio.Group>

<div className="w-3/4 p-5">
{!hasActiveFilters ? (
<WelcomeMessage hasFilters={false} />
) : filteredTools.length > 0 ? (
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
{filteredTools.map((tool) => (
<Card key={tool.name} className="bg-[#2D6A4F] text-white">
<Title level={3} className="text-white">
{tool.name}
</Title>
<Paragraph className="text-gray-100">
{tool.summary}
</Paragraph>
<a
href={tool.link}
target="_blank"
rel="noopener noreferrer"
className="text-blue-200 hover:text-blue-100"
>
Visit Website
</a>
</Card>
))}
</div>
) : (
<WelcomeMessage hasFilters={true} />
)}
</div>
<div className="flex justify-between mt-6">
<Button onClick={handleSkip} className="mr-4">
Skip
</Button>
<Button
type="primary"
onClick={handleNext}
disabled={!answers[currentQuestion]?.[0]}
>
{currentQuestionIndex === QUESTIONNAIRE_ORDER.length - 1
? "See Recommendations"
: "Next"}
</Button>
</div>
</div>
)
Expand Down
Loading