115 lines
6.4 KiB
TypeScript
115 lines
6.4 KiB
TypeScript
import { useState } from 'react';
|
||
import { ChevronIcon } from '../ui/icons/ChevronIcon';
|
||
|
||
interface FAQItem {
|
||
question: string;
|
||
answer: string;
|
||
}
|
||
|
||
const FAQ_ITEMS: FAQItem[] = [
|
||
{
|
||
question: 'What is this application?',
|
||
answer:
|
||
'Narrowit is an interactive map that visualises property-level data across England and Wales. It combines Land Registry sale prices, EPC energy certificates, TfL journey times, deprivation indices, crime statistics, broadband speeds, school ratings, road noise levels, ethnicity demographics, and OpenStreetMap points of interest into a single explorable view.',
|
||
},
|
||
{
|
||
question: 'Where does the data come from?',
|
||
answer:
|
||
'All data comes from open government and community sources. Property prices are from HM Land Registry, energy certificates from MHCLG, transport times from TfL, deprivation scores from the English Indices of Deprivation 2025, crime data from data.police.uk, school ratings from Ofsted, broadband from Ofcom, noise from Defra, ethnicity from the 2021 Census, and points of interest from OpenStreetMap. See the Data Sources page for full details and links.',
|
||
},
|
||
{
|
||
question: 'What are the coloured hexagons on the map?',
|
||
answer:
|
||
'The map uses H3 hexagons to aggregate property data at different zoom levels. Each hexagon summarises the properties within it. The colour represents the value of whichever feature you have pinned or are actively filtering — for example, average price or energy rating. Zoom in to see smaller, more detailed hexagons; zoom out for a broader overview.',
|
||
},
|
||
{
|
||
question: 'How do filters work?',
|
||
answer:
|
||
'Use the Filters panel on the left to narrow down properties. Add a filter by clicking a feature name, then drag the range slider to set minimum and maximum values. For categorical features like property type, select or deselect individual values. Only hexagons containing properties that match all active filters are shown. Filters are combined with AND logic — every property must satisfy every filter.',
|
||
},
|
||
{
|
||
question: 'What does the eye icon do on a filter?',
|
||
answer:
|
||
"The eye icon pins a feature as the colour source for the hexagon layer. When pinned, hexagons are coloured by that feature's value range even when you are not actively dragging its slider. This lets you visualise one feature while filtering on others. Click the eye icon again to unpin.",
|
||
},
|
||
{
|
||
question: 'How fresh is the data?',
|
||
answer:
|
||
'Property prices cover all Land Registry transactions up to the most recent quarterly release. EPC data includes certificates issued up to the latest available download. Crime data spans 2023–2025 as yearly averages. TfL journey times are computed from current timetables. Deprivation indices are from the 2025 release. School ratings reflect the latest Ofsted inspections as at April 2025. Broadband data is from Ofcom Connected Nations 2025.',
|
||
},
|
||
{
|
||
question: 'How are EPC records matched to Land Registry sales?',
|
||
answer:
|
||
"EPC and Land Registry records don't share a common identifier, so they are fuzzy-joined by address within each postcode bucket. The pipeline uses token-sorted string similarity with special handling for numeric tokens (house numbers, flat numbers). Matches are assigned greedily from highest similarity score downward so each record is used at most once.",
|
||
},
|
||
{
|
||
question: 'What are Points of Interest (POIs)?',
|
||
answer:
|
||
'POIs are places like cafes, schools, supermarkets, GP surgeries, parks, and train stations extracted from OpenStreetMap and the NaPTAN public transport dataset. Use the POI panel on the right to toggle categories on and off. POIs appear as markers on the map when you are zoomed in far enough.',
|
||
},
|
||
{
|
||
question: 'Can I share a specific view with someone?',
|
||
answer:
|
||
'Yes. The URL updates automatically as you pan, zoom, and change filters. Click the Share button in the header to copy the current URL to your clipboard. Anyone who opens that link will see the same view, filters, and active POI categories.',
|
||
},
|
||
{
|
||
question: 'How do I see individual properties?',
|
||
answer:
|
||
'Click on a hexagon to open the Properties panel on the right. It lists all matching properties within that hexagon, showing address, price, and key features. Use "Load more" at the bottom to paginate through large hexagons.',
|
||
},
|
||
{
|
||
question: 'Why are some hexagons grey?',
|
||
answer:
|
||
'Grey hexagons contain properties that have data but fall outside the range of your currently pinned or active feature. This gives you a sense of where properties exist even when their values are outside your selected range.',
|
||
},
|
||
{
|
||
question: 'Does this work on mobile?',
|
||
answer:
|
||
'The app is designed for desktop browsers where you have enough screen space for the map, filter panel, and POI/properties panel side by side. It will load on mobile but the experience is best on a larger screen.',
|
||
},
|
||
];
|
||
|
||
function FAQItemCard({ item }: { item: FAQItem }) {
|
||
const [open, setOpen] = useState(false);
|
||
|
||
return (
|
||
<div className="bg-white dark:bg-navy-800 rounded-lg border border-warm-200 dark:border-navy-700">
|
||
<button
|
||
className="w-full text-left px-5 py-4 flex items-center justify-between gap-4"
|
||
onClick={() => setOpen(!open)}
|
||
>
|
||
<span className="font-medium text-warm-900 dark:text-warm-100">{item.question}</span>
|
||
<ChevronIcon
|
||
direction="down"
|
||
className={`w-5 h-5 shrink-0 text-warm-400 dark:text-warm-500 transform ${open ? 'rotate-180' : ''}`}
|
||
/>
|
||
</button>
|
||
{open && (
|
||
<div className="px-5 pb-4">
|
||
<p className="text-sm text-warm-700 dark:text-warm-300 leading-relaxed">{item.answer}</p>
|
||
</div>
|
||
)}
|
||
</div>
|
||
);
|
||
}
|
||
|
||
export default function FAQPage() {
|
||
return (
|
||
<div className="flex-1 overflow-y-auto bg-warm-50 dark:bg-navy-950">
|
||
<div className="max-w-3xl mx-auto px-6 py-8">
|
||
<h1 className="text-2xl font-bold text-warm-900 dark:text-warm-100 mb-2">
|
||
Frequently Asked Questions
|
||
</h1>
|
||
<p className="text-warm-600 dark:text-warm-400 mb-6">
|
||
Common questions about how Narrowit works, where the data comes from, and how to use the
|
||
map.
|
||
</p>
|
||
<div className="space-y-3">
|
||
{FAQ_ITEMS.map((item, index) => (
|
||
<FAQItemCard key={index} item={item} />
|
||
))}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|