# 4. Pages & Components Reference

This is a detailed tour of every route and reusable component, including the data structures you'll edit. For *how to change* things, see [Content Editing Recipes](05-content-editing-recipes.md).

---

## Pages (routes)

### Home — `app/page.tsx` → `/`

A thin wrapper that stacks four components:

```tsx
<Header />        // nav bar
<Landing_bg />    // hero
<Landing />       // everything else on the home page
<Footer />        // footer
```

All the home-page content lives in `Landing_bg` and `Landing` (see [Components](#components) below).

---

### About — `app/about/page.tsx` → `/about`

**Client component.** Sections, top to bottom:

1. **Hero** — full-screen background (`assets/about_bg.png`) with a slow pan animation (`animate-pan-lr`), the "MEET THE DATA CENTER OPERATORS" headline, and a "Follow Our Journey" link to the DCPH LinkedIn.
2. **Who We Are** — text block (`leaders.png` image) describing the alliance, including the **"473 megawatts (MW)"** combined-capacity figure and the **"six pioneering companies"** line. These numbers are hardcoded here.
3. **Purpose / Mission / Vision** — a 3-card flip carousel. Data is in the `cards` array (top of the file). Cards auto-advance every 4s (pauses on hover), flip on hover (desktop) or tap (mobile).
4. **Officers grid** — renders `<OfficerCard officers={officers} />` (the `OfficersSection` component). Data is in the `officers` array.

**Key data structures (edit these):**

- `cards` — `{ id, title, icon, color, content }` for Purpose, Mission, Vision. `icon` is a `react-icons` component; `color` is the accent hex.
- `officers` — `{ imagePath, name, position, linkedIn }`. `imagePath` is an imported image from `assets/`.

**State:** `currentCardIndex` (which card is front), `isPaused` (hover pause), `flippedCard` (which card is flipped). A small `<style jsx global>` block at the bottom defines the 3D-flip CSS helpers.

---

### Why Philippines — `app/whyph/page.tsx` → `/whyph`

**Client component.** Sections:

1. **Hero** — gradient background with a dot pattern, headline, a Philippines map image (`ph.png`), and a **"See Video"** button that opens a modal playing `public/WHY_PHILIPPINES.mp4`.
2. **Advantages accordion** — 6 expandable rows, each with an icon, a label, and 3 sub-items (icon + title + description).

**Key data structure (edit this):**

- `accordionItems` — an array of 6 objects: `{ id, icon, iconAlt, label, content: [{ icon, iconAlt, title, description }, …] }`. All `icon` values are images imported from `assets/`. The six sections are: Strategic Digital Gateway, Talent-Driven Tech Economy, Thriving Investment Policies, Grid-Ready Renewables, Developing Infrastructure, and Cloud-First & AI Vision. Most of the statistics on this page (capacities, dollar figures, etc.) live inside these `description` strings.

**State:** `openIndex` (which accordion row is open; only one at a time), `isVideoModalOpen` (the video modal). A `useEffect` locks page scroll while the modal is open.

---

### Data Centers — `app/data-centers/page.tsx` → `/data-centers`

**Client component.** Lets visitors search/filter member facilities and see them on a map.

**Key data structures (edit these):**

- `locations` — the filter buttons: `["ALL LOCATIONS", "QUEZON CITY", "LAGUNA", "BATANGAS", "RIZAL"]`.
- `facilities` — `{ name, location, tags, linkedin }[]`. `tags` are strings like `"COLOCATION"` / `"HYPERSCALE"` (these drive the card icons).

**How filtering works:** `filteredFacilities` combines the selected location button and the search box text. The same filtered list is passed to both the cards and the `<FacilityMap>`.

**The map** is imported with `next/dynamic` and `ssr: false` — it only loads in the browser (Leaflet needs `window`). While it loads, a "Loading map..." placeholder shows.

---

### `FacilityMap` — `app/data-centers/FacilityMap.tsx`

**Client component.** Renders an OpenStreetMap-tiled Leaflet map with a custom teardrop marker per facility.

**Key data structure (edit this):**

- `facilityCoordinates` — maps a facility **name** to its `{ coords: [lat, lng], color }`. **The name here must exactly match the `name` in the `facilities` array** in `page.tsx`, or the pin won't appear.

Other details:
- `createCustomIcon(color)` builds the teardrop marker via `L.divIcon` (inline HTML/CSS) — this is why the map renders fine even though the default Leaflet PNG markers referenced in the `useEffect` don't exist in `public/` (see [Known Issues](07-known-issues-and-maintenance.md)).
- The map is centered on `[14.0, 121.0]` at zoom `9` (Luzon / CALABARZON area).
- When a filter is active, a "Filtered Results" overlay box lists the visible facilities.

---

### Contact Us — `app/contact-us/page.tsx` → `/contact-us`

**Server component (fully static).** Shows a gradient header, then EMAIL / PHONE / SOCIAL NETWORK blocks, then a "HAVE A QUESTION?" card with an **Email Us** button (a `mailto:info@dcph.org` link).

**Edit directly in the JSX** — there's no data array here. Contact values:
- Emails: `info@dcph.org`, `secretariat@datacenterph.org`
- Phone: `+63 908 399 4599` (Mon–Fri 8am–5pm PHT)
- LinkedIn: `https://www.linkedin.com/company/datacenterph/`

> ⚠️ The same phone/email also appear in `components/Landing.tsx` (home-page "Connect With Us" section). Update **both** when these change.

---

### News listing — `app/news/page.tsx` → `/news`

**Client component.** Two parts:

1. **Featured carousel** (Embla) driven by the `newsItems` array — large cards with "Read More" links.
2. **Searchable grid** driven by the `newsArticles` array — a text search box filters by title/description.

**Key data structures (edit these):**

- `newsItems` — featured cards: `{ id, tag, title, description, date, image, slug }`.
- `newsArticles` — grid cards: `{ id, category, title, description, date, image, slug }`.

`image` is a URL string into `public/images/...`. `slug` must match a key in the `articles` object in `[slug]/page.tsx` so "Read More" links resolve.

---

### News article — `app/news/[slug]/page.tsx`

**Server component, async.** This is a **dynamic route**: the URL segment becomes `slug`, and the page looks up `articles[slug]`. If there's no match, it renders Next's 404 (`notFound()`).

**Key data structure (edit this):**

- `articles` — an object keyed by slug. Each article is:
  ```ts
  {
    slug, title, date, author, image,
    content: [ { type, text?, images? }, … ]
  }
  ```
  `content` is an ordered list of **blocks**. Each block's `type` is one of:
  | `type`        | Renders as                                   | Uses        |
  | ------------- | -------------------------------------------- | ----------- |
  | `paragraph`   | A `<p>` (the first paragraph is emphasized)  | `text`      |
  | `heading`     | A large `<h2>`                               | `text`      |
  | `subheading`  | A smaller `<h3>`                             | `text`      |
  | `image`       | A single full-width image                    | `images[0]` |
  | `image-grid`  | A 2-column image grid                        | `images`    |

**SEO:** the file also exports `generateMetadata`, which builds per-article `<title>`, Open Graph, and Twitter card tags. It uses `BASE_URL = "https://dcph.ph"` — update this constant if the production domain ever changes.

**`BackButton.tsx`** (client) is a small "Back" button used in the article hero; it calls `router.back()`.

---

## Components

### `Header.tsx` (client)

The site-wide top navigation.

- **Data:** `navLinks` array — `{ label, href }` for Home, About Us, Why Philippines, Data Centers, Contact Us, News. **Edit this array to change the menu.**
- **Active link:** uses `usePathname()` to highlight the current page.
- **Responsive:** a horizontal pill-shaped nav on large screens (`lg:`), and a hamburger button that toggles a dropdown menu (`menuOpen` state) on small screens.
- Logo links back to `/`.

### `Footer.tsx` (server)

- Brand block (logo + name + tagline), two columns of links, a gradient divider line, and a copyright line that auto-updates the year via `new Date().getFullYear()`.
- **Links are hardcoded in the JSX** (About Us, Why PH, Data Centers, News & Resources, Contact Us) — this is a second, separate copy of the navigation; keep it in sync with `Header`'s `navLinks` if you add/rename pages.

### `Landing.tsx` (client) — the home page body

Several sections in one file:

1. **Operator marquee** — an auto-scrolling strip of grayscale operator logos (`animate-infinite-scroll`). Logos are duplicated to make the loop seamless.
2. **"Meet our Operators"** — full-bleed expanding photo panels. Data is the `operators` array (`{ src, alt, name, linkedin }`). Hover/click expands a panel and reveals the name + a LinkedIn button.
3. **"Why the Philippines?"** — text + checklist (the four bullet strings are inline) + the `Ph_map.png` image + a CTA to `/whyph`.
4. **"Latest News & Updates"** — **three hardcoded news cards** (not generated from data) linking to article slugs. ⚠️ These are a third copy of news content — see the [news recipe](05-content-editing-recipes.md#recipe-add-or-edit-a-news-article).
5. **"Connect With Us"** — phone + email + a CTA to `/contact-us`. ⚠️ Contact values duplicated from the Contact page.

**State:** `isImageHovered`/`activePanel` (operator panels), `activeCard`/`scrollContainerRef` (mobile news scroll dots).

### `Landing_bg.tsx` (client) — the home hero

- **Data:** `backgroundImages` — an array of 6 operator photos that **cross-fade automatically every 3 seconds** (`setInterval` in a `useEffect`).
- Contains the main headline ("Data Center Operators of The Philippines"), a description, and two CTAs (`/about`, `/contact-us`).

### `Officers.tsx` (server)

- Exports two things in one file: an internal `OfficerCard` (single card) and the default export `OfficersSection` (the whole grid). The About page imports the default export — confusingly aliased as `OfficerCard` there.
- **Props:** `OfficersSection` takes `officers: { imagePath, name, position, linkedIn }[]` and renders each as a card whose whole surface links to the person's LinkedIn.

### `News.tsx` (server) — *currently unused*

A self-contained presentational news card (`title`, `summary`, `date`, `imageUrl`, `category`). It is **not imported anywhere**; the News page builds its own cards inline. Left in the repo but inert. Safe to delete if you want to tidy up.

Next: [Content Editing Recipes →](05-content-editing-recipes.md)
