Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
agnlez committed Aug 28, 2024
1 parent 2a08915 commit 8efe280
Show file tree
Hide file tree
Showing 54 changed files with 1,042 additions and 309 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"lint": "next lint"
},
"dependencies": {
"@artsy/fresnel": "7.1.4",
"@hookform/resolvers": "3.9.0",
"@lukemorales/query-key-factory": "1.3.4",
"@mailchimp/mailchimp_marketing": "3.0.80",
Expand Down
13 changes: 13 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file added public/images/partners/ciencias-ulisboa.webp
Binary file not shown.
Binary file added public/images/partners/coastwatch.webp
Binary file not shown.
Binary file added public/images/partners/dreamocracy.webp
Binary file not shown.
Binary file added public/images/partners/ecsa.webp
Binary file not shown.
Binary file added public/images/partners/forest-world.webp
Binary file not shown.
Binary file added public/images/partners/iaac.webp
Binary file not shown.
Binary file added public/images/partners/necu.webp
Binary file not shown.
Binary file added public/images/partners/nilu.webp
Binary file not shown.
Binary file added public/images/partners/nioo.webp
Binary file not shown.
Binary file added public/images/partners/niva.webp
Binary file not shown.
Binary file added public/images/partners/nordeco.webp
Binary file not shown.
Binary file added public/images/partners/polski-alarm-smogowy.webp
Binary file not shown.
Binary file added public/images/partners/rivm.webp
Binary file not shown.
Binary file added public/images/partners/tracasa.webp
Binary file not shown.
Binary file added public/images/partners/un-wcmc.webp
Binary file not shown.
Binary file added public/images/partners/university-copenhagen.webp
Binary file not shown.
Binary file added public/images/partners/vito.webp
Binary file not shown.
Binary file added public/images/partners/vizzuality.webp
Binary file not shown.
10 changes: 3 additions & 7 deletions src/app/cases/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ import queryKeys from '@/lib/query-keys';

import CASE_STUDIES from '@/data/case-studies';

import CaseDetailSidebar from '@/containers/case-detail/sidebar';
import Map from '@/containers/cases/map';
import Sidebar from '@/containers/cases/sidebar';
import ResponsiveCaseDetailPage from '@/app/cases/[id]/responsive';

import { INITIAL_FILTERS_STATE } from '@/containers/cases/store';

const prefetchData = async (queryClient: QueryClient, id: string) => {
Expand All @@ -32,10 +31,7 @@ export default async function CaseDetail({ params: { id } }: { params: { id: str

return (
<HydrationBoundary state={dehydrate(queryClient)}>
<Sidebar>
<CaseDetailSidebar />
</Sidebar>
<Map />
<ResponsiveCaseDetailPage />
</HydrationBoundary>
);
}
24 changes: 24 additions & 0 deletions src/app/cases/[id]/responsive.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
'use client';

import CaseDetailSidebar from '@/containers/case-detail/sidebar';
import CasesMap from '@/containers/cases/map';
import Sidebar from '@/containers/cases/sidebar';
import { Media } from '@/containers/media';

export default function ResponsiveCaseDetailPage() {
return (
<>
<Media lessThan="md" className="flex-1">
<CaseDetailSidebar />
</Media>
<Media greaterThanOrEqual="md" className="relative flex flex-1">
<>
<Sidebar>
<CaseDetailSidebar />
</Sidebar>
<CasesMap />
</>
</Media>
</>
);
}
20 changes: 3 additions & 17 deletions src/app/cases/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,9 @@ import queryKeys from '@/lib/query-keys';

import CASE_STUDIES from '@/data/case-studies';

import CaseStudies from '@/containers/cases';
import Map from '@/containers/cases/map';
import Sidebar from '@/containers/cases/sidebar';
import { INITIAL_FILTERS_STATE } from '@/containers/cases/store';
import CaseStudiesTotal from '@/containers/cases/total';
import ResponsiveCasesPage from '@/app/cases/responsive';

import { ScrollArea } from '@/components/ui/scroll-area';
import { INITIAL_FILTERS_STATE } from '@/containers/cases/store';

const prefetchData = async (queryClient: QueryClient) => {
const caseStudiesService = new CaseStudyService(CASE_STUDIES, {}, {});
Expand All @@ -29,17 +25,7 @@ export default async function Cases() {

return (
<HydrationBoundary state={dehydrate(queryClient)}>
<Sidebar>
<div className="px-[60px]">
<CaseStudiesTotal />
</div>
<ScrollArea className="pb-8">
<div className="px-[60px]">
<CaseStudies />
</div>
</ScrollArea>
</Sidebar>
<Map />
<ResponsiveCasesPage />
</HydrationBoundary>
);
}
85 changes: 85 additions & 0 deletions src/app/cases/responsive.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
'use client';

import { useRef, useState } from 'react';

import { motion, useInView } from 'framer-motion';

import CaseStudies from '@/containers/cases';
import FiltersContent from '@/containers/cases/header/filters/filters-dropdown/content';
import MobileFiltersDropdown from '@/containers/cases/header/filters/filters-dropdown/mobile';
import CasesMap from '@/containers/cases/map';
import Sidebar from '@/containers/cases/sidebar';
import CaseStudiesTotal from '@/containers/cases/total';
import { Media } from '@/containers/media';

import { ScrollArea } from '@/components/ui/scroll-area';

export default function ResponsiveCasesPage() {
const ref = useRef<HTMLDivElement>(null);
const inView = useInView(ref, { amount: 0.15 });
const [isFiltersOpen, setIsFiltersOpen] = useState(false);

const handleOpenFilters = () => {
setIsFiltersOpen((prev) => !prev);
};

const closeFilters = () => {
setIsFiltersOpen(false);
};

return (
<>
<Media lessThan="md">
<motion.div
className="fixed top-0 z-20 w-full justify-between border-b border-b-grey-800/20 bg-white duration-75 ease-in-out"
variants={{
initial: { opacity: 0, y: '-100%', display: 'none' },
show: { opacity: 1, y: '0', display: 'flex' },
}}
initial="initial"
animate={inView ? 'initial' : 'show'}
>
<CaseStudiesTotal className="flex w-full items-center justify-between gap-4 px-4 text-lg">
<MobileFiltersDropdown onClickSearch={() => {}} onClickFilters={handleOpenFilters} />
</CaseStudiesTotal>
</motion.div>
<div className="px-4 md:p-[50px]" ref={ref}>
<CaseStudiesTotal className="flex items-baseline justify-between gap-4 text-xl">
<MobileFiltersDropdown onClickSearch={() => {}} onClickFilters={handleOpenFilters} />
</CaseStudiesTotal>
</div>
<ScrollArea className="pb-8">
<div className="px-4 md:p-[50px]">
<CaseStudies />
</div>
</ScrollArea>
<motion.div
className="fixed h-[calc(100%-128px)] rounded-t-3xl bg-grey-800 px-10 py-4"
variants={{
initial: { opacity: 0, display: 'none', bottom: '-100%' },
show: { opacity: 1, display: 'flex', bottom: 0 },
}}
initial="initial"
animate={isFiltersOpen ? 'show' : 'initial'}
>
<FiltersContent onSetFiltersDone={closeFilters} onClearFiltersDone={closeFilters} />
</motion.div>
</Media>
<Media greaterThanOrEqual="md" className="relative flex flex-1">
<>
<Sidebar>
<div className="px-[60px]">
<CaseStudiesTotal className="text-xl" />
</div>
<ScrollArea className="pb-8">
<div className="px-[60px]">
<CaseStudies />
</div>
</ScrollArea>
</Sidebar>
<CasesMap />
</>
</Media>
</>
);
}
13 changes: 13 additions & 0 deletions src/app/head.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
'use client';

import { mediaStyles } from '@/containers/media';

function RootHead() {
return (
<head>
<style key="fresnel-css" dangerouslySetInnerHTML={{ __html: mediaStyles }} type="text/css" />
</head>
);
}

export default RootHead;
2 changes: 2 additions & 0 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Lexend } from 'next/font/google';
import type { Metadata } from 'next';

import './globals.css';
import RootHead from '@/app/head';
import LayoutProviders from '@/app/providers';

const lexend = Lexend({ subsets: ['latin'], weight: ['100', '400', '500', '700'] });
Expand Down Expand Up @@ -51,6 +52,7 @@ export default function RootLayout({ children }: Readonly<PropsWithChildren>) {
return (
<LayoutProviders>
<html lang="en">
<RootHead />
<body className={lexend.className}>{children}</body>
</html>
</LayoutProviders>
Expand Down
6 changes: 5 additions & 1 deletion src/app/providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { PropsWithChildren } from 'react';

import { QueryClient, QueryClientProvider } from '@tanstack/react-query';

import { MediaContextProvider } from '@/containers/media';

function makeQueryClient() {
return new QueryClient({
defaultOptions: {
Expand Down Expand Up @@ -39,7 +41,9 @@ export default function LayoutProviders({ children }: PropsWithChildren) {

return (
<>
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
<MediaContextProvider>
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
</MediaContextProvider>
</>
);
}
59 changes: 59 additions & 0 deletions src/components/animated-menu/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { useRef, useEffect } from 'react';

import { useCycle, motion } from 'framer-motion';

import { MenuToggle } from '@/components/animated-menu/toggle';

export const useDimensions = (ref) => {
const dimensions = useRef({ width: 0, height: 0 });

useEffect(() => {
dimensions.current.width = ref.current.offsetWidth;
dimensions.current.height = ref.current.offsetHeight;
}, [ref]);

return dimensions.current;
};

const sidebar = {
open: (height = 1000) => ({
clipPath: `circle(${height * 2 + 200}px at 710px 42px)`,
transition: {
type: 'spring',
stiffness: 20,
restDelta: 2,
},
}),
closed: {
clipPath: 'circle(30px at 710px 42px)',
transition: {
// delay: 0.5,
type: 'spring',
stiffness: 400,
damping: 40,
},
},
};

export default function AnimatedMenu() {
const [isOpen, toggleOpen] = useCycle(false, true);
const containerRef = useRef(null);
const { height } = useDimensions(containerRef);

return (
<motion.nav
initial={false}
animate={isOpen ? 'open' : 'closed'}
custom={height}
ref={containerRef}
className="absolute bottom-0 right-0 top-0 w-[740px]"
>
<motion.div
className="absolute bottom-0 right-0 top-0 w-[740px] bg-orange-500"
variants={sidebar}
/>
{/*<Navigation />*/}
<MenuToggle toggle={() => toggleOpen()} />
</motion.nav>
);
}
40 changes: 40 additions & 0 deletions src/components/animated-menu/toggle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import * as React from 'react';

import { motion } from 'framer-motion';

const Path = (props) => (
<motion.path
fill="transparent"
strokeWidth="3"
stroke="hsl(0, 0%, 18%)"
strokeLinecap="round"
{...props}
/>
);

export const MenuToggle = ({ toggle }) => (
<button onClick={toggle} className="absolute right-[18px] top-[33px] rounded-full">
<svg width="23" height="23" viewBox="0 0 23 23">
<Path
variants={{
closed: { d: 'M 2 2.5 L 20 2.5' },
open: { d: 'M 3 16.5 L 17 2.5' },
}}
/>
<Path
d="M 2 9.423 L 20 9.423"
variants={{
closed: { opacity: 1 },
open: { opacity: 0 },
}}
transition={{ duration: 0.1 }}
/>
<Path
variants={{
closed: { d: 'M 2 16.346 L 20 16.346' },
open: { d: 'M 3 2.5 L 17 16.346' },
}}
/>
</svg>
</button>
);
9 changes: 6 additions & 3 deletions src/components/app-menu/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { motion } from 'framer-motion';
import { HiOutlineMenuAlt4 } from 'react-icons/hi';

import { SECTIONS } from '@/containers/header';
import { Media } from '@/containers/media';

import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';

Expand All @@ -14,9 +15,11 @@ export default function AppMenu() {
<Popover>
<PopoverTrigger asChild className="group">
<div className="relative flex items-center gap-3">
<span className="absolute -left-[calc(100%+8px)] top-1/2 hidden -translate-y-1/2 uppercase text-white group-hover:flex">
Menu
</span>
<Media greaterThanOrEqual="md">
<span className="absolute -left-[calc(100%+8px)] top-1/2 hidden -translate-y-1/2 uppercase text-white group-hover:flex">
Menu
</span>
</Media>
<motion.button
type="button"
className="relative flex h-[52px] w-[52px] items-center justify-center rounded-full bg-grey-800 p-4 after:absolute after:left-1/2 after:top-1/2 after:h-11 after:w-11 after:-translate-x-1/2 after:-translate-y-1/2 after:rounded-full after:border-2 after:border-white"
Expand Down
Loading

0 comments on commit 8efe280

Please sign in to comment.