git.iko.soy/rowtype-yoga/psfp
on master help sign in
178 lines 5.3 kB history raw
1module Landing where
3import Prelude
4import Data.Foldable (for_)
5import Data.Maybe (Maybe(..))
6import Data.Monoid (power)
7import Data.Nullable (null)
8import Effect (Effect)
9import Effect.Uncurried (runEffectFn1)
10import Icon.Logo (logo)
11import React.Basic (Ref)
12import React.Basic.DOM as R
13import React.Basic.Emotion as E
14import React.Basic.Events (EventHandler, handler_)
15import React.Basic.Helpers (jsx)
16import React.Basic.Hooks (ReactComponent, reactComponent, readRefMaybe, useRef)
17import React.Basic.Hooks as React
18import Unsafe.Coerce (unsafeCoerce)
19import Web.HTML (window)
20import Web.HTML.HTMLElement (getBoundingClientRect)
21import Web.HTML.HTMLElement as HTMLElement
22import Yoga ((/>), (</), (</*), (</*>), (</>))
23import Yoga.Block as Block
24import Yoga.Block.Atom.Button.Types as ButtonType
25import Yoga.Block.Container.Style (DarkOrLightMode(..), colour)
26import Yoga.Block.Internal (NodeRef)
27import Yoga.SVG.Image (mkLandingPageBackground)
28import Yoga.Scroll.Hook (useScrollYPosition)
30classes =
31 { landing:
32 E.css
33 { width: E.str "100vw"
34 , height: E.str "100vh"
35 , gridArea: E.str "landing"
36 }
37 , textLayer:
38 E.css
39 { position: E.str "absolute"
40 , width: E.str "100%"
41 , height: E.str "100%"
42 , zIndex: E.int 2
43 }
44 , topBar:
45 E.css
46 { width: E.str "100%"
47 , display: E.str "flex"
48 , flexDirection: E.str "row"
49 , height: E.str "90px"
50 , justifyContent: E.str "center"
51 , alignItems: E.str "space-around"
52 }
53 , logo:
54 E.css
55 { fill: E.str colour.text
56 , width: E.str "50px"
57 , height: E.str "50px"
58 , marginTop: E.str "33px"
59 }
60 , welcomeText:
61 E.css
62 { fontSize: E.str "36pt"
63 , marginTop: E.str "33px"
64 , marginLeft: E.str "5vw"
65 }
66 , welcomeCopy:
67 E.css
68 { fontSize: E.str "22pt"
69 , marginTop: E.str "20px"
70 , marginLeft: E.str "5vw"
71 , maxWidth: E.str "400px"
72 }
73 , actionButton:
74 E.css
75 { marginLeft: E.str "5vw"
76 , display: E.str "flex"
77 }
78 , actualActionButton:
79 E.css
80 { paddingLeft: E.str "10px"
81 , paddingRight: E.str "10px"
82 }
83 , landingImage:
84 E.css
85 { position: E.str "absolute"
86 , maxWidth: E.str "none"
87 , width: E.str "min(100%, 1200px)"
88 , height: E.str "100%"
89 }
90 }
92mkLandingPage ∷ Effect (ReactComponent {})
93mkLandingPage = do
94 backgroundImage <- mkLandingPageBackground
95 reactComponent "LandingPage" \{} -> React.do
96 ref <- useRef null
97 scrollY <- useScrollYPosition
98 let
99 themeVariant ∷ DarkOrLightMode
100 themeVariant = DarkMode -- [TODO]
101 backgroundImg =
102 E.element
103 backgroundImage
104 { className: "landing-image"
105 , css: classes.landingImage
106 , themeVariant
107 }
108 button =
109 R.div'
110 </*> { css: classes.actionButton
111 , className: "action-button"
112 , children:
113 [ Block.button
114 </* { onClick: scrollTo ref
115 , buttonType: ButtonType.Primary
116 , css: classes.actualActionButton
117 , className: "lets-go-btn"
118 }
119 /> [ R.text buttonText ]
120 ]
121 }
122 welcomeTitle =
123 R.div'
124 </*> { className: "welcome-text", css: classes.welcomeText, children: [ R.text welcomeText ] }
125 welcomeSubtitle =
126 R.div'
127 </*> { className: "welcome-copy", css: classes.welcomeCopy, children: [ R.text copyText ] }
128 upperBlock =
129 E.element R.div'
130 { ref
131 , css: classes.landing
132 , className: "landing-page"
133 , children:
134 [ backgroundImg
135 , E.element R.div'
136 { className: "text-layer"
137 , css: classes.textLayer
138 , children:
139 [ R.div'
140 </*> { className: "top-bar"
141 , css: classes.topBar
142 , children: [ Block.icon </*> { className: "logo", css: E.css { marginTop: E.var "--s0" }, size: E.var "--s3", icon: logo } ]
143 }
144 , Block.stack
145 </ {}
146 /> [ welcomeTitle
147 , welcomeSubtitle
148 , button
149 ]
150 ]
151 }
152 ]
153 }
154 textBlock = R.text placeholderText
155 content = Block.stack </ {}
156 pure $ Block.container </> { themeVariant: Just themeVariant, content: content [ upperBlock, textBlock ] }
158welcomeText ∷ String
159welcomeText = "Enter the college of Kleisli"
161copyText ∷ String
162copyText = "Let's go!"
164buttonText ∷ String
165buttonText = "I can't wait, let's go!"
167placeholderText ∷ String
168placeholderText = "Franz jagt im komplett verwahrlosten Taxi quer durch Bayern. " `power` 20
170scrollTo ∷ NodeRef -> EventHandler
171scrollTo ref =
172 handler_ do
173 maybeNode <- readRefMaybe ref
174 for_ (maybeNode >>= HTMLElement.fromNode) \n -> do
175 height <- getBoundingClientRect n <#> _.height
176 win <- window
177 runEffectFn1 ((unsafeCoerce win).scrollTo)
178 { top: height, left: 0, behavior: "smooth" }