git.iko.soy/gigawork-coworking/gigawork-coworking.github.io
on master help sign in
499 lines 17 kB history raw
1module Route.Index exposing (ActionData, Data, Model, Msg, route)
3import BackendTask exposing (BackendTask)
4import Element exposing (..)
5import Element.Background as Background
6import Element.Border as Border
7import Element.Font as Font
8import FatalError exposing (FatalError)
9import Head
10import Head.Seo as Seo
11import Html
12import Html.Attributes as Html
13import LanguageTag.Language
14import LanguageTag.Region
15import Pages.Url
16import PagesMsg exposing (PagesMsg)
17import Route
18import RouteBuilder exposing (App, StatelessRoute)
19import Shared
20import UrlPath
21import View exposing (View)
24type alias Model =
25 {}
28type alias Msg =
29 ()
32type alias RouteParams =
33 {}
36type alias Data =
37 { message : String
38 }
41type alias ActionData =
42 {}
45route : StatelessRoute RouteParams Data ActionData
46route =
47 RouteBuilder.single
48 { head = head
49 , data = data
50 }
51 |> RouteBuilder.buildNoState { view = view }
54data : BackendTask FatalError Data
55data =
56 BackendTask.succeed Data
57 |> BackendTask.andMap
58 (BackendTask.succeed "Hello!")
61head :
62 App Data ActionData RouteParams
63 -> List Head.Tag
64head app =
65 Seo.summary
66 { canonicalUrlOverride = Nothing
67 , siteName = "GigaWork"
68 , image =
69 { url = [] |> UrlPath.join |> Pages.Url.fromPath
70 , alt = ""
71 , dimensions = Nothing
72 , mimeType = Nothing
73 }
74 , description = "Преимальный коворкинг у дома"
75 , locale = Just ( LanguageTag.Language.ru, LanguageTag.Region.ru )
76 , title = "GigaWork"
77 }
78 |> Seo.website
81view :
82 App Data ActionData RouteParams
83 -> Shared.Model
84 -> View (PagesMsg Msg)
85view app shared =
86 { title = "GigaWork"
87 , body =
88 column [ width (fill |> maximum 700), centerX, padding 22, spacing 76 ]
89 [ column []
90 [ el [ unbounded, Font.color green, Font.heavy, Font.size 72 ]
91 (text "GigaWork")
92 , el
93 [ paddingEach { top = 9, right = 0, left = 18, bottom = 0 }
94 , noto
95 , Font.size 18
96 , Font.extraBold
97 ]
98 (text "Премиальный коворкинг у дома")
99 ]
100 , callToAction
101 , column [ spacing 27, width fill ]
102 [ subtitle "Адрес"
103 , paragraph [ noto, Font.size 18, Font.extraBold ] [ text "Москва, Рублевское шоссе, 22" ]
104 , el [ width fill, height (px 400) ] <|
105 html <|
106 Html.iframe
107 [ Html.src "https://yandex.ru/map-widget/v1/?um=constructor%3A6021061543ae5cffca6803ac7a0fa84e727d918c403c59250d18022f582f81d0&amp;source=constructor"
108 , Html.height 400
109 , Html.attribute "frameborder" "0"
110 ]
111 []
112 ]
113 , column [ spacing 24, width fill ]
114 [ subtitle "Преимущества"
115 , wrappedRow [ spacing 16, centerX, width fill ]
116 [ card
117 { title = "Удобное расположение"
118 , body = "10 минут от метро Молодежная.\nБесплатная парковка."
119 , image = image [ width fill, height fill ] { src = "/map.png", description = "Карта" }
120 }
121 , card
122 { title = "Эргономичная мебель"
123 , body = "Каждое рабочее место оснащено креслом Herman Miller."
124 , image = image [ width fill, height fill ] { src = "/chair.png", description = "Кресло Herman Miller Mirra" }
125 }
126 , card
127 { title = "Свежий кофе"
128 , body = "Каждую неделю заказываем для вас свежеобжаренный кофе."
129 , image = image [ width fill, height fill ] { src = "/coffee.jpg", description = "Кофе" }
130 }
131 , card
132 { title = "Проводной интернет"
133 , body = "Каждое рабочее место оснащено выходом USB-C с зарядкой и интернетом."
134 , image = image [ width fill, height fill ] { src = "/usb-c.jpg", description = "Кабель USB-C" }
135 }
136 , card
137 { title = "Принтер"
138 , body = "Для вашего пользования есть лазерный принтер."
139 , image = image [ width fill, height fill ] { src = "/printer.jpg", description = "Принтер" }
140 }
141 , card
142 { title = "Лаундж-зона"
143 , body = "Предусмотрена лаундж-зона для отдыха."
144 , image = image [ width fill, height fill ] { src = "/sofa.jpg", description = "Диван" }
145 }
146 , card
147 { title = "Кабинки для звонков"
148 , body = "Чтобы не мешать друг другу в коворкинге стоят кабинки для звонков."
149 , image = mockImage
150 }
151 , card
152 { title = "Комфортные условия"
153 , body = "В коворкинге установлен кондиционер и очиститель воздуха."
154 , image = image [ width fill, height fill ] { src = "/air.jpg", description = "Воздух" }
155 }
156 ]
157 ]
158 , column [ spacing 27, width fill ]
159 [ subtitle "График работы"
160 , row [ width fill, spaceEvenly ]
161 [ workDayCard { title = "Пн", from = "9:00", to = "18:00" }
162 , workDayCard { title = "Вт", from = "9:00", to = "18:00" }
163 , workDayCard { title = "Ср", from = "9:00", to = "18:00" }
164 , workDayCard { title = "Чт", from = "9:00", to = "18:00" }
165 , workDayCard { title = "Пт", from = "9:00", to = "18:00" }
166 , weekendDayCard { title = "Сб" }
167 , weekendDayCard { title = "Вс" }
168 ]
169 ]
170 , column [ spacing 27, width fill ]
171 [ subtitle "Цена"
172 , row [ width fill, spaceEvenly ]
173 [ priceCard { title = "1 день", price = "2 000 ₽", subtitle = "" }
174 , priceCard { title = "1 месяц", price = "25 000 ₽", subtitle = "" }
175 , priceCard { title = "3 месяца", price = "66 000 ₽", subtitle = "22 000 ₽ / месяц" }
176 , priceCard { title = "6 месяца", price = "120 000 ₽", subtitle = "20 000 ₽ / месяц" }
177 ]
178 ]
179 , callToAction
180 , el [ height (px 76) ] none
181 ]
182 }
185mockImage : Element msg
186mockImage =
187 el
188 [ Background.color (rgb 0.3 0.3 0.3)
189 , width (px 1000)
190 , height (px 1000)
191 ]
192 none
195subtitle : String -> Element msg
196subtitle t =
197 paragraph [ Font.color green, Font.size 36, Font.heavy, unbounded ] [ text t ]
200unbounded : Attribute msg
201unbounded =
202 Font.family [ Font.typeface "Unbounded" ]
205noto : Attribute msg
206noto =
207 Font.family [ Font.typeface "Noto Sans" ]
210green : Color
211green =
212 rgb255 32 195 145
215background : Color
216background =
217 rgb255 243 243 243
220button : String -> Element msg
221button t =
222 el
223 [ Border.rounded 1000
224 , Border.shadow
225 { offset = ( 4, 4 )
226 , size = 0
227 , blur = 16
228 , color = rgba255 0 0 0 0.2
229 }
230 , mouseOver
231 [ Border.shadow
232 { offset = ( 4, 4 )
233 , size = 0
234 , blur = 20
235 , color = rgba255 0 0 0 0.2
236 }
237 ]
238 , mouseDown
239 [ Border.shadow
240 { offset = ( 4, 4 )
241 , size = 0
242 , blur = 8
243 , color = rgba255 0 0 0 0.2
244 }
245 ]
246 , pointer
247 , animate
248 ]
249 <|
250 el
251 [ Border.rounded 1000
252 , Border.shadow
253 { offset = ( -4, -4 )
254 , size = 0
255 , blur = 16
256 , color = rgba 255 255 255 1
257 }
258 , mouseOver
259 [ Border.shadow
260 { offset = ( -4, -4 )
261 , size = 0
262 , blur = 20
263 , color = rgba 255 255 255 1
264 }
265 ]
266 , mouseDown
267 [ Border.shadow
268 { offset = ( -4, -4 )
269 , size = 0
270 , blur = 8
271 , color = rgba 255 255 255 0.8
272 }
273 ]
274 , animate
275 ]
276 <|
277 el
278 [ Background.color background
279 , Border.rounded 1000
280 , Border.innerShadow
281 { offset = ( 4, 4 )
282 , size = 0
283 , blur = 4
284 , color = rgba255 255 255 255 1
285 }
286 , mouseOver
287 [ Border.innerShadow
288 { offset = ( 4, 4 )
289 , size = 0
290 , blur = 8
291 , color = rgba255 255 255 255 1
292 }
293 ]
294 , mouseDown
295 [ Border.innerShadow
296 { offset = ( 4, 4 )
297 , size = 0
298 , blur = 2
299 , color = rgba255 255 255 255 1
300 }
301 ]
302 , animate
303 ]
304 <|
305 el
306 [ Border.innerShadow
307 { offset = ( -4, -4 )
308 , size = 0
309 , blur = 4
310 , color = rgba255 0 0 0 0.15
311 }
312 , mouseOver
313 [ Border.innerShadow
314 { offset = ( -4, -4 )
315 , size = 0
316 , blur = 8
317 , color = rgba255 0 0 0 0.2
318 }
319 ]
320 , mouseDown
321 [ Border.innerShadow
322 { offset = ( -4, -4 )
323 , size = 0
324 , blur = 2
325 , color = rgba255 0 0 0 0.2
326 }
327 ]
328 , padding 24
329 , Border.rounded 1000
330 , Font.extraBold
331 , Font.size 18
332 , animate
333 ]
334 (text t)
337card : { title : String, body : String, image : Element msg } -> Element msg
338card { title, body, image } =
339 el
340 [ Border.shadow
341 { offset = ( -4, -4 )
342 , blur = 16
343 , size = 0
344 , color = rgb 255 255 255
345 }
346 , Border.rounded 16
347 , width (minimum 312 <| fill)
348 , alignTop
349 ]
350 <|
351 column
352 [ Border.shadow
353 { offset = ( 4, 4 )
354 , blur = 16
355 , size = 0
356 , color = rgba 0 0 0 0.2
357 }
358 , Border.rounded 16
359 , width fill
360 ]
361 [ column
362 [ padding 16
363 , spacing 8
364 ]
365 [ paragraph [ unbounded, Font.extraBold, Font.size 18, spacing 2 ] [ text title ]
366 , paragraph [ noto, Font.size 14, spacing 1 ] [ text body ]
367 ]
368 , el
369 [ height (px 156)
370 , width fill
371 , clip
372 , centerX
373 , centerY
374 , Border.roundEach
375 { topLeft = 0
376 , topRight = 0
377 , bottomLeft = 16
378 , bottomRight = 16
379 }
380 ]
381 image
382 ]
385animate : Attribute msg
386animate =
387 htmlAttribute <| Html.class "animate"
390indentedCard : { title : String, body : Element msg, color : Color, minWidth : Int } -> Element msg
391indentedCard { title, body, color, minWidth } =
392 el
393 [ Background.color color
394 , Border.shadow
395 { offset = ( 4, 4 )
396 , blur = 16
397 , size = 0
398 , color = rgba255 0 0 0 0.2
399 }
400 , Border.rounded 16
401 ]
402 <|
403 el
404 [ Border.shadow
405 { offset = ( -4, -4 )
406 , blur = 16
407 , size = 0
408 , color = rgb255 255 255 255
409 }
410 , Border.rounded 16
411 ]
412 <|
413 column [ padding 4, width (minimum minWidth <| fill), height (px 132) ]
414 [ el
415 [ height (px 38)
416 , unbounded
417 , width fill
418 , Font.heavy
419 , Font.size 14
420 , Border.innerShadow
421 { offset = ( 4, 4 )
422 , blur = 4
423 , size = 0
424 , color = rgba255 0 0 0 0.15
425 }
426 , Border.roundEach
427 { topLeft = 14
428 , topRight = 14
429 , bottomLeft = 0
430 , bottomRight = 0
431 }
432 , Background.color background
433 ]
434 <|
435 el
436 [ width fill
437 , height fill
438 , Border.innerShadow
439 { offset = ( -4, -4 )
440 , blur = 4
441 , size = 0
442 , color = rgb255 255 255 255
443 }
444 , Border.roundEach
445 { topLeft = 14
446 , topRight = 14
447 , bottomLeft = 0
448 , bottomRight = 0
449 }
450 ]
451 <|
452 el [ centerX, centerY ]
453 (text title)
454 , body
455 ]
458workDayCard : { title : String, from : String, to : String } -> Element msg
459workDayCard { title, from, to } =
460 indentedCard
461 { title = title
462 , body =
463 column [ centerX, centerY, unbounded, Font.size 14, Font.heavy, spacing 5 ] <|
464 List.map (el [ centerX ])
465 [ text from, text "—", text to ]
466 , color = background
467 , minWidth = 65
468 }
471weekendDayCard : { title : String } -> Element msg
472weekendDayCard { title } =
473 indentedCard
474 { title = title
475 , body =
476 el [ centerX, centerY, unbounded, Font.size 14, Font.heavy, spacing 5 ] <|
477 el [ centerX ] (text "Вых.")
478 , color = rgb255 246 214 214
479 , minWidth = 65
480 }
483priceCard : { title : String, price : String, subtitle : String } -> Element msg
484priceCard cfg =
485 indentedCard
486 { title = cfg.title
487 , color = background
488 , body =
489 column [ centerX, centerY, spacing 5 ] <|
490 [ el [ centerX, unbounded, Font.size 14, Font.heavy ] (text cfg.price)
491 , el [ centerX, noto, Font.size 14, Font.regular ] (text cfg.subtitle)
492 ]
493 , minWidth = 128
494 }
497callToAction : Element msg
498callToAction =
499 el [ centerX ] <| link [] { url = "https://t.me/ilyakooo0", label = button "Узнать о свободных местах" }