diff --git a/public/images/deforestation.webp b/public/images/deforestation.webp new file mode 100644 index 000000000..d1fc29c0e Binary files /dev/null and b/public/images/deforestation.webp differ diff --git a/public/images/explose-small.svg b/public/images/explose-small.svg index bdcb4528c..fd217aca9 100644 --- a/public/images/explose-small.svg +++ b/public/images/explose-small.svg @@ -3,16 +3,17 @@ - - + - - diff --git a/public/images/og.jpg b/public/images/og.jpg new file mode 100644 index 000000000..d925734ba Binary files /dev/null and b/public/images/og.jpg differ diff --git a/src/app/dashboard/page.tsx b/src/app/dashboard/page.tsx index ea92d6309..5e9d6fcac 100644 --- a/src/app/dashboard/page.tsx +++ b/src/app/dashboard/page.tsx @@ -1,18 +1,17 @@ "use client"; -import clsx from "clsx"; import dynamic from "next/dynamic"; import React, { useEffect, useState } from "react"; -import { FaEye } from "react-icons/fa"; import "@/lib/env"; +import CustomDashboardSection from "@/components/CustomDashboardSection"; import DashboardSection from "@/components/DashboardSection"; - -import { fetchData } from "@/pages/api/chart"; import IntroBlock from "@/components/IntroBlock"; import JoinBlock from "@/components/JoinBlock"; -import TitleBlock from "@/components/TitleBlock"; import Summary, { SummaryLinksProps } from "@/components/Summary"; +import TitleBlock from "@/components/TitleBlock"; + +import { fetchData } from "@/pages/api/chart"; const DashboardChart = dynamic(() => import("@/components/DashboardChart"), { ssr: false, @@ -36,6 +35,76 @@ const summary: SummaryLinksProps = [ }, ], }, + { + title: "Companies", + sublinks: [ + { + label: "Main producers of open-net salmon", + targetId: "top-comp", + }, + { + label: "The new threat: on land-based aquaculture farms", + targetId: "top-land", + }, + { + label: "The future of land-based aquaculture farms", + targetId: "future-land-based", + }, + ], + }, + { + title: "Biodiversity", + sublinks: [ + { + label: "Deforestation", + targetId: "deforestation", + }, + { + label: "Escapes", + targetId: "escapes-rates", + }, + ], + }, + { + title: "Animal welfare", + sublinks: [ + { + label: "Stress in land-based facilities", + targetId: "salmon-collapse", + }, + { + label: "Mortality rate", + targetId: "hyper-growth", + }, + ], + }, + { + title: "Climate", + sublinks: [ + { + label: "Carbon", + targetId: "salmon-collapse", + }, + ], + }, + { + title: "Social", + sublinks: [ + { + label: "/", + targetId: "salmon-collapse", + }, + ], + }, + { + title: "Alternatives", + sublinks: [ + { + label: "Nutrition matrix", + targetId: "salmon-collapse", + }, + ], + }, ]; const DashboardPage = () => { @@ -48,12 +117,20 @@ const DashboardPage = () => { +
- + + +
+ +
+ + +
@@ -73,15 +150,6 @@ const SalmonCollapseSection = () => { - - - }*/ content="The Atlantic salmon was added to the IUCN Red List of Threatened Species in December 2023. This is largely due to overfishing, habitat degradation, particularly caused by dams blocking migratory routes, as well as climate change altering their environments, impacting their growth and survival rates." /> ); @@ -102,13 +170,13 @@ const TopCountriesSection = () => { data: [], layout: {}, }); + const fetchGraphData = async () => { + const mapResponse = await fetchData("graphs", "evolution-map"); + setMapData(mapResponse); + }; useEffect(() => { - const fetchGraphData = async () => { - const mapResponse = await fetchData("evolution-map"); - setMapData(mapResponse); - }; fetchGraphData(); - }, [mapData]); + }, []); if (!mapData) { return <>; @@ -137,16 +205,21 @@ const TopCountriesSection = () => { ); }; +const SalmonConsumptionSection = () => { + return ( + + ); +}; + const MainProductionSection = () => { return ( - CTA - - }*/ content="Small artisanal salmon farms have given way to industrial aquaculture. In a few decades, the market has become dominated by a handful of multinational corporations. Mowi, formerly known as Marine Harvest, is the leader in the sector. The company operates in 25 countries." /> ); @@ -158,7 +231,14 @@ const LandPlantsSection = () => { -
+

The future of land-based aquaculture farms @@ -233,6 +316,37 @@ const LandPlantsSection = () => { ); }; +const SalmonConsumptionBisSection = () => { + return ( + + ); +}; + +const DeforestationSection = () => { + return ( + + ); +}; + +const EscapeSection = () => { + return ( + + ); +}; const AntibioticSection = () => { return ( diff --git a/src/app/page.tsx b/src/app/page.tsx index 2c144d403..722474d83 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -4,6 +4,8 @@ import clsx from "clsx"; import Image from "next/image"; import * as React from "react"; import "@/lib/env"; +import dynamic from "next/dynamic"; +const Plot = dynamic(() => import("react-plotly.js"), { ssr: false, }) import "../styles/page.css"; @@ -11,6 +13,9 @@ import Edito from "@/components/Edito"; import IconCard from "@/components/IconCard"; import IntroBlock from "@/components/IntroBlock"; import JoinBlock from "@/components/JoinBlock"; +import { useState, useEffect } from "react"; +import { fetchData } from "@/pages/api/chart"; + const HomePage = () => { return ( @@ -34,8 +39,8 @@ export default HomePage; const BombSection = () => { return ( -
-
+
+
{ const ExplodeSection = () => { return ( -
-
    +
    +

    + The salmon industry is a bomb with multiple impacts +

    +
      -
    • - -
    • -
    • - -
    • -
    • - -
    • -
    • - -
    • -
    • - -
    • -
    + > +
  • + +
  • +
  • + +
  • +
  • + +
  • +
  • + +
  • +
  • + +
  • +
+
); }; @@ -125,6 +135,7 @@ const EditoSection = () => { small: "/images/storytelling/health-400.jpg", medium: "/images/storytelling/health-600.jpg", large: "/images/storytelling/health-1200.jpg", + caption: "Photo credit: Ramji / Bob Brown Foundation", }, }, { @@ -176,6 +187,22 @@ const EditoSection = () => { }; const BusinessSection = () => { + const [plot, setPlot] = useState({ + data: [], + layout: {}, + }); + const fetchGraphData = async () => { + const response = await fetchData("graphs", "hyper-growth-grouped"); + setPlot(response); + }; + useEffect(() => { + fetchGraphData(); + }, []); + + if (!plot) { + return <>; + } + return (
@@ -186,15 +213,9 @@ const BusinessSection = () => { Salmon production, dominated by a handful of multinationals, has experienced hyper-growth on a global scale for several decades.

- - +
+ +
); diff --git a/src/app/to-act/page.tsx b/src/app/to-act/page.tsx new file mode 100644 index 000000000..0979e5cd7 --- /dev/null +++ b/src/app/to-act/page.tsx @@ -0,0 +1,15 @@ +"use client"; + +import * as React from "react"; +import "@/lib/env"; +import IntroBlock from "@/components/IntroBlock"; + +const ToActPage = () => { + return ( + <> + + + ); +}; + +export default ToActPage; diff --git a/src/components/CustomDashboardSection.tsx b/src/components/CustomDashboardSection.tsx new file mode 100644 index 000000000..75166ec87 --- /dev/null +++ b/src/components/CustomDashboardSection.tsx @@ -0,0 +1,32 @@ +import Image from "next/image"; +import React from "react"; + +const CustomDashboardSection = ({ + title, + id, + mainContent, + content, + src, +}: { + title?: string | undefined; + mainContent?: string; + content?: string | undefined; + id: string; + src: string; +}) => { + return ( +
+
+
+

{title}

+

{mainContent}

+

{content}

+
+
+ {id} +
+
+
+ ); +}; +export default CustomDashboardSection; diff --git a/src/components/DashboardChart.tsx b/src/components/DashboardChart.tsx index 1d848d3d2..92809e3b4 100644 --- a/src/components/DashboardChart.tsx +++ b/src/components/DashboardChart.tsx @@ -1,6 +1,9 @@ import { Data } from "plotly.js-dist-min"; import React from "react"; -import Plot from "react-plotly.js"; +// import Plot from "react-plotly.js"; +import dynamic from "next/dynamic"; +const Plot = dynamic(() => import("react-plotly.js"), { ssr: false, }) + const DashboardChart = ({ data, diff --git a/src/components/DashboardSection.tsx b/src/components/DashboardSection.tsx index e3bd5ea28..894a112d7 100644 --- a/src/components/DashboardSection.tsx +++ b/src/components/DashboardSection.tsx @@ -10,10 +10,12 @@ const DashboardChart = dynamic(() => import("@/components/DashboardChart"), { const DashboardSection = ({ title, id, + mainContent, content, cta, }: { title?: string | undefined; + mainContent?: string; content?: string | undefined; id: string; cta?: ReactNode | undefined; @@ -22,17 +24,20 @@ const DashboardSection = ({ data: [], layout: {}, }); + const [isLoading, setIsLoading] = useState(true); useEffect(() => { const fetchGraphData = async () => { - const response = await fetchData(id); - setChartData(response); - setIsLoading(false); + if (id.length > 0) { + const response = await fetchData("graphs", id); + setChartData(response); + setIsLoading(false); + } }; fetchGraphData(); - }, [chartData, id]); + }, [id]); - if (!chartData || !id) { + if (!chartData) { return <>; } @@ -40,7 +45,8 @@ const DashboardSection = ({
-

{title}

+

{title}

+

{mainContent}

{content}

{cta &&
{cta}
} diff --git a/src/components/Edito.tsx b/src/components/Edito.tsx index d120e590d..bd97bbe24 100644 --- a/src/components/Edito.tsx +++ b/src/components/Edito.tsx @@ -66,10 +66,17 @@ const IconCard = ({
- + {image.small && ( )} @@ -82,9 +89,12 @@ const IconCard = ({ width={600} height={600} alt="" + className="w-full" /> - {image.caption &&
{image.caption}
} + {image.caption && ( +
{image.caption}
+ )}
) : null}
diff --git a/src/components/IconCard.tsx b/src/components/IconCard.tsx index 5458f4a35..6bd5162a5 100644 --- a/src/components/IconCard.tsx +++ b/src/components/IconCard.tsx @@ -29,8 +29,10 @@ const IconCard = ({ className="max-[767px]:w-12 max-[767px]:h-12 max-[1023px]:w-24 max-[1023px]:h-24 object-contain" /> ) : null} -

{title}

-

{content}

+

{title}

+

+ {content} +

); }; diff --git a/src/components/IntroBlock.tsx b/src/components/IntroBlock.tsx index 7b2929185..d8c04cf0c 100644 --- a/src/components/IntroBlock.tsx +++ b/src/components/IntroBlock.tsx @@ -23,7 +23,7 @@ const IntroBlock = ({ image ? "h-screen min-h-[300px]" : "min-h-[660px]", )} > -
+
{image && ( import("react-plotly.js"), { ssr: false, }) + +import { useState, useEffect } from "react"; +import { fetchData } from "@/pages/api/chart"; import PrimaryButton from "@/components/buttons/PrimaryButton"; @@ -11,6 +17,22 @@ const IntroBlock = ({ className?: string; headDark?: boolean; }) => { + + const [plot, setPlot] = useState({ + data: [], + layout: {}, + }); + const fetchGraphData = async () => { + const response = await fetchData("graphs", "alternatives"); + setPlot(response); + }; + useEffect(() => { + fetchGraphData(); + }, []); + + if (!plot) { + return <>; + } return (
- +
+ +
@@ -71,8 +88,8 @@ const IntroBlock = ({

diff --git a/src/components/layout/Navbar.tsx b/src/components/layout/Navbar.tsx index f64c0e99e..985663bd5 100644 --- a/src/components/layout/Navbar.tsx +++ b/src/components/layout/Navbar.tsx @@ -19,6 +19,10 @@ const navItems: NavItemsProps = [ link: "/dashboard", text: "Dashboard", }, + { + link: "/to-act", + text: "To act", + }, { link: "/about", text: "About", @@ -30,7 +34,7 @@ const Navbar = () => { return (
-
+
{ - const dataUrl = process.env.NEXT_PUBLIC_PINKBOMBS_DATA_URL; - const apiKey = process.env.NEXT_PUBLIC_PINKBOMBS_DATA_API_KEY; +"use server"; +export const fetchData = async (apiPath: string, chartName: string) => { + const dataUrl = process.env.PINKBOMBS_DATA_URL; + const apiKey = process.env.PINKBOMBS_DATA_API_KEY; try { - const response = await fetch(`${dataUrl}/${chartType}`, { + const response = await fetch(`${dataUrl}/${apiPath}/${chartName}`, { method: "GET", headers: { "X-API-Key": apiKey, diff --git a/tailwind.config.ts b/tailwind.config.ts index 6f14516a7..145181fcd 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -36,7 +36,7 @@ export default { }, screens: { xs: "500px", - "2xl": "1515px", + "2xl": "1530px", "3xl": "2000px", }, keyframes: {