|
1 | | -import { NextPage } from "next" |
2 | | -import Precursor from "../components/Precursor" |
3 | | -import ReactPageScroller from 'react-page-scroller'; |
4 | | -import { useEffect, useState } from "react"; |
| 1 | +import { NextPage } from "next"; |
| 2 | +import Precursor from "../components/Precursor"; |
| 3 | +import { useState } from "react"; |
5 | 4 | import PageInfo from "../components/PageInfo"; |
6 | | -import { Committee, PageText } from "@prisma/client"; |
| 5 | +import { PageText } from "@prisma/client"; |
7 | 6 | import Page from "../components/Page"; |
8 | | -import PageMargins from "../components/PageMargins"; |
9 | 7 | import Button from "../components/Button"; |
10 | 8 | import { CommitteeWithMembers } from "../types"; |
11 | 9 | import Divider from "../components/Divider"; |
12 | | -import { prisma } from '../prisma/prismaclient'; |
13 | | - |
14 | | -const NavBall = (props: { index: number; committeeyear: string; currentPage: number; scrollTo: (to: number) => void }) => { |
15 | | - return ( |
16 | | - <div onClick={() => { props.scrollTo(props.index) }} className="h-0 w-0 p-2.5 flex justify-end relative items-center m-px navBallBox cursor-pointer"> |
17 | | - <span className="transition-all opacity-0 navBallLabel">{props.committeeyear}</span> |
18 | | - <span className={`navBall ${props.index === props.currentPage ? 'bg-slate-100' : ''} border visible p-1.5 border-slate-100 opacity-50 rounded-full m-2 transition-all duration-200`}></span> |
19 | | - </div> |
20 | | - ) |
21 | | -}; |
22 | | - |
| 10 | +import { prisma } from "../prisma/prismaclient"; |
23 | 11 |
|
24 | 12 | export const getServerSideProps = async () => { |
25 | | - |
26 | 13 | const text = await prisma.pageText.findFirst({ |
27 | 14 | where: { |
28 | | - page: "pateter" |
29 | | - } |
30 | | - }) |
| 15 | + page: "pateter", |
| 16 | + }, |
| 17 | + }); |
31 | 18 |
|
32 | 19 | let allCommittees = await prisma.committee.findMany({ |
33 | 20 | include: { |
34 | | - members: true |
35 | | - } |
36 | | - }) |
| 21 | + members: true, |
| 22 | + }, |
| 23 | + }); |
37 | 24 |
|
38 | 25 | // Database entries are not necessarily in order, and needs to be sorted |
39 | | - allCommittees.sort((a,b) => b.year - a.year) |
| 26 | + allCommittees.sort((a, b) => b.year - a.year); |
40 | 27 | // Remove the current year from the list |
41 | | - allCommittees.shift() |
| 28 | + allCommittees.shift(); |
42 | 29 |
|
43 | 30 | return { |
44 | | - props: { text: text, allCommittees: allCommittees } |
45 | | - } |
46 | | -} |
| 31 | + props: { text: text, allCommittees: allCommittees }, |
| 32 | + }; |
| 33 | +}; |
47 | 34 |
|
48 | 35 | interface PateterProps { |
49 | | - text: PageText |
50 | | - allCommittees: CommitteeWithMembers[] |
| 36 | + text: PageText; |
| 37 | + allCommittees: CommitteeWithMembers[]; |
51 | 38 | } |
52 | 39 |
|
53 | 40 | const Pateter: NextPage<PateterProps> = ({ text, allCommittees }) => { |
| 41 | + const [showToTopButton, setShowToTopButton] = useState(false); |
| 42 | + const [showScrollDownButton, setShowScrollDownButton] = useState(true); |
54 | 43 |
|
55 | | - const [currentPage, setCurrentPage] = useState<number>(0) |
| 44 | + function handleScroll() { |
| 45 | + const boundary = document.querySelector("#boundary"); |
| 46 | + const pateter = document.querySelector("#pateter"); |
56 | 47 |
|
57 | | - const changeBgOpacity = (index: number) => { |
58 | | - const fp = document.getElementById("first-page") |
59 | | - if (!fp) return |
60 | | - if (index === 0) { |
61 | | - fp.style.background = "rgba(0,0,0,0.8)" |
62 | | - } else { |
63 | | - fp.style.background = "rgba(0,0,0,0.9)" |
64 | | - } |
65 | | - } |
66 | | - const scrollTo = (index: number) => { |
67 | | - setCurrentPage(index) |
68 | | - } |
| 48 | + if (!boundary) return; |
| 49 | + if (!pateter) return; |
69 | 50 |
|
70 | | - const [topButtonShown, setTopButtonShown] = useState<boolean>(false) |
| 51 | + setShowToTopButton(boundary.getBoundingClientRect().top <= 0); |
71 | 52 |
|
72 | | - const toggleTopButton = (index: number) => { |
73 | | - index === 0 ? setTopButtonShown(false) : setTopButtonShown(true) |
| 53 | + console.log(pateter.scrollTop); |
| 54 | + setShowScrollDownButton(pateter.scrollTop <= 0); |
74 | 55 | } |
75 | 56 |
|
76 | | - const [currentYear, setCurrentYear] = useState<number>(0) |
| 57 | + function scrollToFirst() { |
| 58 | + const boundary = document.querySelector("#boundary"); |
77 | 59 |
|
78 | | - const handlePageChange = (index: number) => { |
79 | | - setCurrentPage(index) |
80 | | - changeBgOpacity(index) |
81 | | - toggleTopButton(index) |
82 | | - index === 0 ? setCurrentYear(new Date().getFullYear()) : setCurrentYear(allCommittees[index-1].year) // kind of ugly but there's no better way? |
83 | | - }; |
| 60 | + if (!boundary) return; |
84 | 61 |
|
85 | | - // set currentyear to current year with useEffect |
86 | | - useEffect(() => { |
87 | | - setCurrentYear(new Date().getFullYear()) |
88 | | - }, []) |
| 62 | + boundary.scrollIntoView({ behavior: "smooth" }); |
| 63 | + } |
89 | 64 |
|
90 | 65 | return ( |
91 | 66 | <> |
92 | | - <Page blackout unrestrictChildren currentYear={currentYear}> |
93 | | - <ReactPageScroller |
94 | | - animationTimer={700} |
95 | | - animationTimerBuffer={700} |
96 | | - renderAllPagesOnFirstRender={true} |
97 | | - onBeforePageScroll={handlePageChange} |
98 | | - customPageNumber={currentPage} |
| 67 | + <Page blackout ignoreMargins> |
| 68 | + <div |
| 69 | + id="pateter" |
| 70 | + className="snap-y snap-mandatory flex flex-col items-center h-screen overflow-y-auto" |
| 71 | + onScroll={() => handleScroll()} |
99 | 72 | > |
100 | | - <PageMargins> |
101 | | - <PageInfo heading="Pateter"> |
102 | | - {text.content} |
103 | | - </PageInfo> |
| 73 | + <div className="snap-start h-full flex flex-col items-center w-10/12 lg:w-3/4 min-h-screen"> |
| 74 | + <PageInfo heading="Pateter">{text.content}</PageInfo> |
104 | 75 | <Divider /> |
105 | | - |
106 | | - <div className="absolute bottom-10 flex flex-col gap-4 items-center cursor-pointer py-2" onClick={() => scrollTo(1)}> |
| 76 | + <div |
| 77 | + className={`absolute bottom-10 flex flex-col gap-4 items-center cursor-pointer py-2 transition duration-700 ${ |
| 78 | + showScrollDownButton |
| 79 | + ? "opacity-100 pointer-events-auto" |
| 80 | + : "opacity-0 pointer-events-none" |
| 81 | + }`} |
| 82 | + onClick={() => scrollToFirst()} |
| 83 | + > |
107 | 84 | <p className="text-sm italic">Skrolla för pateter</p> |
108 | | - <img className="downarrow w-10 transition opacity-60" src={"/down.svg"} alt="arrow down" /> |
| 85 | + <img |
| 86 | + className="downarrow w-10 transition opacity-60" |
| 87 | + src={"/down.svg"} |
| 88 | + alt="arrow down" |
| 89 | + /> |
109 | 90 | </div> |
110 | | - </PageMargins> |
111 | | - |
112 | | - {allCommittees.map(committee => ( |
113 | | - <div key={committee.year}> |
| 91 | + </div> |
| 92 | + {/* used to to know whether user has scrolled far enough */} |
| 93 | + <div id="boundary"></div>{" "} |
| 94 | + {allCommittees.map((committee) => ( |
| 95 | + <div key={committee.year} className="snap-start"> |
114 | 96 | <Precursor committee={committee} /> |
115 | 97 | </div> |
116 | 98 | ))} |
117 | | - |
118 | | - </ReactPageScroller> |
119 | | - |
120 | | - <div className="fixed flex flex-col items-center -right-2 lg:right-4 self-center top-1/4"> |
121 | | - <NavBall index={0} scrollTo={() => scrollTo(0)} currentPage={currentPage} committeeyear={"Till toppen"} ></NavBall> |
122 | | - {allCommittees.map((committee: Committee, index) => ( |
123 | | - <NavBall key={index} index={index + 1} scrollTo={() => scrollTo(index + 1)} currentPage={currentPage} committeeyear={committee.year.toString().slice(-2)}></NavBall> |
124 | | - ))} |
125 | | - </div> |
126 | | - <div className={`fixed right-10 bottom-10 transition-opacity duration-300 ${topButtonShown ? 'opacity-100' : 'opacity-0 pointer-events-none'}`}> |
127 | | - <Button action={() => scrollTo(0)}> |
128 | | - Tillbaka till toppen |
129 | | - </Button> |
130 | 99 | </div> |
131 | 100 | </Page> |
| 101 | + <div |
| 102 | + className={`fixed right-10 bottom-10 transition-opacity duration-300 ${ |
| 103 | + showToTopButton |
| 104 | + ? "opacity-100 pointer-events-auto" |
| 105 | + : "opacity-0 pointer-events-none" |
| 106 | + }`} |
| 107 | + > |
| 108 | + <Button |
| 109 | + color="bg-black/20" |
| 110 | + action={() => { |
| 111 | + document |
| 112 | + .querySelector("#pateter") |
| 113 | + ?.scrollTo({ top: 0, behavior: "smooth" }); |
| 114 | + }} |
| 115 | + > |
| 116 | + Tillbaka till toppen |
| 117 | + </Button> |
| 118 | + </div> |
132 | 119 | </> |
133 | | - ) |
134 | | -} |
| 120 | + ); |
| 121 | +}; |
135 | 122 |
|
136 | | -export default Pateter |
| 123 | +export default Pateter; |
0 commit comments