aboutsummaryrefslogtreecommitdiff
path: root/frontend/src
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/src')
-rw-r--r--frontend/src/Cart.elm7
-rw-r--r--frontend/src/Catalog.elm62
-rw-r--r--frontend/src/Checkout.elm7
-rw-r--r--frontend/src/Icons.elm15
-rw-r--r--frontend/src/Login.elm41
-rw-r--r--frontend/src/Main.elm125
-rw-r--r--frontend/src/Product.elm35
-rw-r--r--frontend/src/Signup.elm49
-rw-r--r--frontend/src/Styles.elm104
-rw-r--r--frontend/src/Utils.elm45
10 files changed, 398 insertions, 92 deletions
diff --git a/frontend/src/Cart.elm b/frontend/src/Cart.elm
index 58fb72e..44d5a0d 100644
--- a/frontend/src/Cart.elm
+++ b/frontend/src/Cart.elm
@@ -2,9 +2,10 @@ module Cart exposing (..)
2 2
3import Browser 3import Browser
4import Browser.Navigation as Nav 4import Browser.Navigation as Nav
5import Html exposing (..) 5import Html
6import Html.Attributes exposing (..) 6import Html.Styled exposing (..)
7import Html.Events exposing (..) 7import Html.Styled.Attributes exposing (..)
8import Html.Styled.Events exposing (..)
8import Http 9import Http
9import Json.Decode as D 10import Json.Decode as D
10import Json.Encode as Encode 11import Json.Encode as Encode
diff --git a/frontend/src/Catalog.elm b/frontend/src/Catalog.elm
index d00cb92..5b233f2 100644
--- a/frontend/src/Catalog.elm
+++ b/frontend/src/Catalog.elm
@@ -2,15 +2,16 @@ module Catalog exposing (..)
2 2
3import Browser 3import Browser
4import Browser.Navigation as Nav 4import Browser.Navigation as Nav
5import Html exposing (..) 5import Css exposing (..)
6import Html.Attributes exposing (..) 6import Html
7import Html.Events exposing (..) 7import Html.Styled exposing (..)
8import Html.Styled.Attributes exposing (..)
9import Html.Styled.Events exposing (..)
8import Http 10import Http
9import Json.Decode as D 11import Json.Decode as D
10import Json.Encode as Encode 12import Json.Encode as Encode
13import Styles exposing (..)
11import Tuple exposing (..) 14import Tuple exposing (..)
12import Url
13import Url.Parser as P exposing ((</>), Parser, int, oneOf, s, string)
14import Utils exposing (..) 15import Utils exposing (..)
15 16
16 17
@@ -37,7 +38,7 @@ type alias Filters =
37 38
38defaultFilters : Filters 39defaultFilters : Filters
39defaultFilters = 40defaultFilters =
40 Filters ( -1, 10000 ) ( 0, 5 ) 41 Filters ( -1, 100000 ) ( 0, 5 )
41 42
42 43
43type alias Model = 44type alias Model =
@@ -199,18 +200,26 @@ viewFilters model =
199 inp = 200 inp =
200 Maybe.withDefault 0 << String.toFloat 201 Maybe.withDefault 0 << String.toFloat
201 in 202 in
202 div [] 203 div
203 [ div [] 204 []
204 [ text "Price" 205 [ div
205 , select [ onInput (ChangePriceLower << inp) ] (viewRange 0 priceRange) 206 [ css
207 [ bigHeading
208 , paddingBottom (px 12)
209 ]
210 ]
211 [ text "Filters" ]
212 , div []
213 [ div [] [ text "Price" ]
214 , furbySelect [ onInput (ChangePriceLower << inp), style "appearance" "none" ] (viewRange 0 priceRange)
206 , text "to" 215 , text "to"
207 , select [ onInput (ChangePriceUpper << inp) ] (viewRange 50000 priceRange) 216 , furbySelect [ onInput (ChangePriceUpper << inp), style "appearance" "none" ] (viewRange 50000 priceRange)
208 ] 217 ]
209 , div [] 218 , div []
210 [ text "Rating" 219 [ div [] [ text "Rating" ]
211 , select [ onInput (ChangeRatingLower << inp) ] (viewRange 1 ratingRange) 220 , furbySelect [ onInput (ChangeRatingLower << inp), style "appearance" "none" ] (viewRange 1 ratingRange)
212 , text "to" 221 , text "to"
213 , select [ onInput (ChangeRatingUpper << inp) ] (viewRange 5 ratingRange) 222 , furbySelect [ onInput (ChangeRatingUpper << inp), style "appearance" "none" ] (viewRange 5 ratingRange)
214 ] 223 ]
215 ] 224 ]
216 225
@@ -234,8 +243,25 @@ view model =
234 div [] [ text <| viewStatus Loading ] 243 div [] [ text <| viewStatus Loading ]
235 244
236 _ -> 245 _ ->
237 div [] 246 div
238 [ div [] [ viewFilters model ] 247 [ css [ padding (px 40) ] ]
239 , ul [] 248 [ div
240 (filterProducts model |> List.map viewProduct) 249 [ css
250 [ float left
251 , Css.width (pct 20)
252 ]
253 ]
254 [ viewFilters model ]
255 , div
256 [ css
257 [ float left
258 , Css.width (pct 80)
259 ]
260 ]
261 [ div [ css [ bigHeading ] ] [ text "Products" ]
262 , ul
263 [ css [ padding (px 0) ]
264 ]
265 (filterProducts model |> List.map viewProduct)
266 ]
241 ] 267 ]
diff --git a/frontend/src/Checkout.elm b/frontend/src/Checkout.elm
index c60da0d..4df20d8 100644
--- a/frontend/src/Checkout.elm
+++ b/frontend/src/Checkout.elm
@@ -2,9 +2,10 @@ module Checkout exposing (..)
2 2
3import Browser 3import Browser
4import Browser.Navigation as Nav 4import Browser.Navigation as Nav
5import Html exposing (..) 5import Html
6import Html.Attributes exposing (..) 6import Html.Styled exposing (..)
7import Html.Events exposing (..) 7import Html.Styled.Attributes exposing (..)
8import Html.Styled.Events exposing (..)
8import Http 9import Http
9import Json.Decode as D 10import Json.Decode as D
10import Json.Encode as Encode 11import Json.Encode as Encode
diff --git a/frontend/src/Icons.elm b/frontend/src/Icons.elm
new file mode 100644
index 0000000..d3b862f
--- /dev/null
+++ b/frontend/src/Icons.elm
@@ -0,0 +1,15 @@
1module Icons exposing (..)
2
3import FeatherIcons exposing (toHtml)
4import Html
5import Html.Styled exposing (..)
6import Html.Styled.Attributes exposing (..)
7import Html.Styled.Events exposing (..)
8
9
10convert =
11 Html.Styled.fromUnstyled << toHtml []
12
13
14loginIcon =
15 convert FeatherIcons.logIn
diff --git a/frontend/src/Login.elm b/frontend/src/Login.elm
index dd168f0..87657bb 100644
--- a/frontend/src/Login.elm
+++ b/frontend/src/Login.elm
@@ -2,11 +2,15 @@ module Login exposing (..)
2 2
3import Browser 3import Browser
4import Browser.Navigation as Nav 4import Browser.Navigation as Nav
5import Html exposing (..) 5import Css exposing (..)
6import Html.Attributes exposing (..) 6import Html
7import Html.Events exposing (..) 7import Html.Styled exposing (..)
8import Html.Styled.Attributes exposing (..)
9import Html.Styled.Events exposing (..)
8import Http 10import Http
11import Icons exposing (..)
9import Json.Encode as Encode 12import Json.Encode as Encode
13import Styles exposing (..)
10import Url 14import Url
11import Url.Parser as P exposing ((</>), Parser, int, oneOf, s, string) 15import Url.Parser as P exposing ((</>), Parser, int, oneOf, s, string)
12 16
@@ -91,7 +95,7 @@ viewStatus : LoginStatus -> String
91viewStatus ls = 95viewStatus ls =
92 case ls of 96 case ls of
93 NotLoggedIn -> 97 NotLoggedIn ->
94 "Not Logged In" 98 ""
95 99
96 InvalidLogin -> 100 InvalidLogin ->
97 "Invalid Login" 101 "Invalid Login"
@@ -105,15 +109,30 @@ viewStatus ls =
105 109
106viewInput : String -> String -> String -> (String -> msg) -> Html msg 110viewInput : String -> String -> String -> (String -> msg) -> Html msg
107viewInput t p v toMsg = 111viewInput t p v toMsg =
108 input [ type_ t, placeholder p, value v, onInput toMsg ] [] 112 loginInputField [ type_ t, placeholder p, value v, onInput toMsg ] []
113
114
115fieldPadding =
116 css
117 [ paddingTop (px 10)
118 , paddingBottom (px 10)
119 ]
109 120
110 121
111view : Model -> Html Msg 122view : Model -> Html Msg
112view model = 123view model =
113 div [] 124 div
114 [ div [] [ viewInput "text" "Enter name here" model.username UserEntered ] 125 [ css
115 , div [] [ viewInput "password" "Password" model.password PassEntered ] 126 [ margin auto
116 , div [] [ button [ onClick LoginPressed ] [ text "Login" ] ] 127 , marginTop (pct 10)
117 , div [] [ text (viewStatus model.loginStatus) ] 128 , padding (px 20)
118 , div [] [ text "Don't have an account? ", a [ href "/signup" ] [ text "Register now!" ] ] 129 , Css.width (pct 30)
130 ]
131 ]
132 [ div [ fieldPadding, css [ bigHeading ] ] [ text "Login" ]
133 , div [ fieldPadding ] [ viewInput "text" "Enter name here" model.username UserEntered ]
134 , div [ fieldPadding ] [ viewInput "password" "Password" model.password PassEntered ]
135 , div [ css [ textAlign center ], fieldPadding ] [ furbyButton [ onClick LoginPressed ] [ text "Login" ] ]
136 , div [ css [ textAlign center ] ] [ text (viewStatus model.loginStatus) ]
137 , div [ fieldPadding ] [ text "Don't have an account? ", a [ href "/signup" ] [ text "Register now!" ] ]
119 ] 138 ]
diff --git a/frontend/src/Main.elm b/frontend/src/Main.elm
index f1883a1..ea80921 100644
--- a/frontend/src/Main.elm
+++ b/frontend/src/Main.elm
@@ -5,14 +5,17 @@ import Browser.Navigation as Nav
5import Cart 5import Cart
6import Catalog 6import Catalog
7import Checkout 7import Checkout
8import Html exposing (..) 8import Css exposing (..)
9import Html.Attributes exposing (..) 9import Html
10import Html.Events exposing (..) 10import Html.Styled exposing (..)
11import Html.Styled.Attributes exposing (..)
12import Html.Styled.Events exposing (..)
11import Http 13import Http
12import Json.Encode as Encode 14import Json.Encode as Encode
13import Login 15import Login
14import Product 16import Product
15import Signup 17import Signup
18import Styles exposing (..)
16import Url 19import Url
17import Url.Parser as P exposing ((</>), Parser, int, oneOf, s, string) 20import Url.Parser as P exposing ((</>), Parser, int, oneOf, s, string)
18 21
@@ -276,56 +279,93 @@ subscriptions _ =
276view : Model -> Browser.Document Msg 279view : Model -> Browser.Document Msg
277view model = 280view model =
278 case model.location of 281 case model.location of
282 HomePage ->
283 { title = "Login"
284 , body =
285 -- model.loginModel
286 -- |> Login.view
287 -- |> Html.Styled.map LoginMessage
288 -- |> toUnstyled
289 -- |> List.singleton
290 div []
291 [ ul []
292 (List.map
293 (\l ->
294 li []
295 [ a [ href l ] [ text l ] ]
296 )
297 [ "/login", "/catalog", "/cart" ]
298 )
299 ]
300 |> toUnstyled
301 |> List.singleton
302 }
303
279 LoginPage -> 304 LoginPage ->
280 { title = "Login" 305 { title = "Login"
281 , body = [ Html.map LoginMessage (Login.view model.loginModel) ] 306 , body =
307 model.loginModel
308 |> Login.view
309 |> Html.Styled.map LoginMessage
310 |> toUnstyled
311 |> List.singleton
282 } 312 }
283 313
284 SignupPage -> 314 SignupPage ->
285 { title = "Signup" 315 { title = "Signup"
286 , body = [ Html.map SignupMessage (Signup.view model.signupModel) ]
287 }
288
289 HomePage ->
290 { title = "URL Interceptor"
291 , body = 316 , body =
292 [ text "The current URL is: " 317 model.signupModel
293 , b [] [ text (Url.toString model.url) ] 318 |> Signup.view
294 , ul [] 319 |> Html.Styled.map SignupMessage
295 [ viewLink "/login" 320 |> toUnstyled
296 , viewLink "/catalog" 321 |> List.singleton
297 , viewLink "/cart"
298 , viewLink "/signup"
299 ]
300 ]
301 } 322 }
302 323
303 NotFoundPage -> 324 NotFoundPage ->
304 { title = "404 - Not Found" 325 { title = "404 - Not Found"
305 , body = 326 , body =
306 [ text "404 - Not Found" 327 div []
307 , a [ href "/" ] [ text "Go back >" ] 328 [ text "404 - Not Found"
308 ] 329 , a [ href "/" ] [ text "Go back >" ]
330 ]
331 |> toUnstyled
332 |> List.singleton
309 } 333 }
310 334
311 CatalogPage -> 335 CatalogPage ->
312 { title = "Catalog" 336 { title = "Catalog"
313 , body = pageWrap model (Html.map CatalogMessage (Catalog.view model.catalogModel)) 337 , body =
338 model.catalogModel
339 |> Catalog.view
340 |> Html.Styled.map CatalogMessage
341 |> pageWrap model
314 } 342 }
315 343
316 CartPage -> 344 CartPage ->
317 { title = "Cart" 345 { title = "Cart"
318 , body = pageWrap model (Html.map CartMessage (Cart.view model.cartModel)) 346 , body =
347 model.cartModel
348 |> Cart.view
349 |> Html.Styled.map CartMessage
350 |> pageWrap model
319 } 351 }
320 352
321 CheckoutPage -> 353 CheckoutPage ->
322 { title = "Checkout" 354 { title = "Checkout"
323 , body = pageWrap model (Html.map CheckoutMessage (Checkout.view model.checkoutModel)) 355 , body =
356 model.checkoutModel
357 |> Checkout.view
358 |> Html.Styled.map CheckoutMessage
359 |> pageWrap model
324 } 360 }
325 361
326 ProductPage item -> 362 ProductPage item ->
327 { title = "Product " ++ String.fromInt item 363 { title = "Product " ++ String.fromInt item
328 , body = pageWrap model (Html.map ProductMessage (Product.view model.productModel)) 364 , body =
365 model.productModel
366 |> Product.view
367 |> Html.Styled.map ProductMessage
368 |> pageWrap model
329 } 369 }
330 370
331 371
@@ -333,36 +373,49 @@ viewHeader : Model -> Html Msg
333viewHeader model = 373viewHeader model =
334 let 374 let
335 links = 375 links =
336 [ ( "Home", "/" ) 376 [ ( "Catalog", "/catalog" )
337 , ( "Catalog", "/catalog" )
338 , ( "Cart", "/cart" ) 377 , ( "Cart", "/cart" )
339 ] 378 ]
340 in 379 in
341 div [] 380 div
381 [ css
382 [ padding (px 40)
383 , paddingTop (px 3)
384 , paddingBottom (px 3)
385 , textAlign left
386 , backgroundColor theme.secondary
387 ]
388 ]
342 [ List.map 389 [ List.map
343 (\( name, loc ) -> 390 (\( name, loc ) ->
344 li [] 391 li [ css [ display inline ] ]
345 [ a [ href loc ] [ text name ] 392 [ headerLink [ href loc ] [ text name ]
346 ] 393 ]
347 ) 394 )
348 links 395 links
349 ++ [ if model.loginModel.loginStatus /= Login.LoggedIn then 396 ++ [ if model.loginModel.loginStatus /= Login.LoggedIn then
350 li [] [ a [ href "/login" ] [ text "Login" ] ] 397 li [ css [ display inline ] ] [ headerLink [ href "/login" ] [ text "Login" ] ]
351 398
352 else 399 else
353 button [ onClick LogoutPressed ] [ text "Logout" ] 400 furbyButton [ onClick LogoutPressed ] [ text "Logout" ]
354 ] 401 ]
355 |> ul [] 402 |> ul
403 [ css
404 [ listStyle Css.none
405 , padding (px 0)
406 ]
407 ]
356 ] 408 ]
357 409
358 410
359pageWrap : Model -> Html Msg -> List (Html Msg) 411pageWrap : Model -> Html Msg -> List (Html.Html Msg)
360pageWrap model page = 412pageWrap model page =
361 [ div [] 413 div []
362 [ viewHeader model 414 [ viewHeader model
363 , page 415 , page
364 ] 416 ]
365 ] 417 |> toUnstyled
418 |> List.singleton
366 419
367 420
368viewLink : String -> Html msg 421viewLink : String -> Html msg
diff --git a/frontend/src/Product.elm b/frontend/src/Product.elm
index 0ea0ce1..b97a847 100644
--- a/frontend/src/Product.elm
+++ b/frontend/src/Product.elm
@@ -2,14 +2,16 @@ module Product exposing (..)
2 2
3import Browser 3import Browser
4import Browser.Navigation as Nav 4import Browser.Navigation as Nav
5import Html exposing (..) 5import Html
6import Html.Attributes exposing (..) 6import Html.Styled exposing (..)
7import Html.Events exposing (..) 7import Html.Styled.Attributes exposing (..)
8import Html.Styled.Events exposing (..)
8import Http 9import Http
9import Json.Decode as D 10import Json.Decode as D
10import Json.Encode as Encode 11import Json.Encode as Encode
11import Url 12import Url
12import Url.Parser as P exposing ((</>), Parser, int, oneOf, s, string) 13import Url.Parser as P exposing ((</>), Parser, int, oneOf, s, string)
14import Utils exposing (..)
13 15
14 16
15type SubmitStatus 17type SubmitStatus
@@ -25,11 +27,13 @@ type alias Product =
25 , kind : Maybe String 27 , kind : Maybe String
26 , price : Float 28 , price : Float
27 , description : Maybe String 29 , description : Maybe String
30 , src : String
31 , iosSrc : String
28 } 32 }
29 33
30 34
31emptyProduct = 35emptyProduct =
32 Product -1 "" Nothing 0 Nothing 36 Product -1 "" Nothing 0 Nothing "" ""
33 37
34 38
35type alias Rating = 39type alias Rating =
@@ -140,12 +144,14 @@ update msg model =
140 144
141decodeProduct : D.Decoder Product 145decodeProduct : D.Decoder Product
142decodeProduct = 146decodeProduct =
143 D.map5 Product 147 D.map7 Product
144 (D.field "id" D.int) 148 (D.field "id" D.int)
145 (D.field "name" D.string) 149 (D.field "name" D.string)
146 (D.field "kind" (D.nullable D.string)) 150 (D.field "kind" (D.nullable D.string))
147 (D.field "price" D.float) 151 (D.field "price" D.float)
148 (D.field "description" (D.nullable D.string)) 152 (D.field "description" (D.nullable D.string))
153 (D.field "src" D.string)
154 (D.field "ios_src" D.string)
149 155
150 156
151decodeRating : D.Decoder Rating 157decodeRating : D.Decoder Rating
@@ -246,10 +252,21 @@ viewStatus s =
246viewProduct : Product -> Html Msg 252viewProduct : Product -> Html Msg
247viewProduct p = 253viewProduct p =
248 div [] 254 div []
249 [ text p.name 255 [ div [] [ text p.name ]
250 , text <| Maybe.withDefault "" p.kind 256 , div [] [ text <| Maybe.withDefault "" p.kind ]
251 , text <| Maybe.withDefault "" p.description 257 , div [] [ text <| Maybe.withDefault "" p.description ]
252 , text <| String.fromFloat p.price 258 , div [] [ text <| String.fromFloat p.price ]
259 , div []
260 [ modelViewer
261 [ cameraControls
262 , autoRotate
263 , arSrc p.src
264 , arIosSrc p.iosSrc
265 , loading "eager"
266 , arModes "webxr"
267 ]
268 []
269 ]
253 ] 270 ]
254 271
255 272
diff --git a/frontend/src/Signup.elm b/frontend/src/Signup.elm
index 30794e7..028af9c 100644
--- a/frontend/src/Signup.elm
+++ b/frontend/src/Signup.elm
@@ -2,11 +2,14 @@ module Signup exposing (..)
2 2
3import Browser 3import Browser
4import Browser.Navigation as Nav 4import Browser.Navigation as Nav
5import Html exposing (..) 5import Css exposing (..)
6import Html.Attributes exposing (..) 6import Html
7import Html.Events exposing (..) 7import Html.Styled exposing (..)
8import Html.Styled.Attributes exposing (..)
9import Html.Styled.Events exposing (..)
8import Http 10import Http
9import Json.Encode as Encode 11import Json.Encode as Encode
12import Styles exposing (..)
10import Url 13import Url
11import Url.Parser as P exposing ((</>), Parser, int, oneOf, s, string) 14import Url.Parser as P exposing ((</>), Parser, int, oneOf, s, string)
12 15
@@ -178,19 +181,41 @@ viewStatus s =
178 181
179viewInput : String -> String -> String -> (String -> msg) -> Html msg 182viewInput : String -> String -> String -> (String -> msg) -> Html msg
180viewInput t p v toMsg = 183viewInput t p v toMsg =
181 input [ type_ t, placeholder p, value v, onInput toMsg ] [] 184 loginInputField [ type_ t, placeholder p, value v, onInput toMsg ] []
185
186
187fieldPadding =
188 css
189 [ paddingTop (px 10)
190 , paddingBottom (px 10)
191 ]
182 192
183 193
184view : Model -> Html Msg 194view : Model -> Html Msg
185view model = 195view model =
186 div [] 196 div
187 [ div [] [ viewInput "text" "Enter Username" model.username UserEntered ] 197 [ css
188 , div [] [ viewInput "password" "Password" model.password PassEntered ] 198 [ margin auto
189 , div [] [ viewInput "text" "Email" model.emailId EmailEntered ] 199 , marginTop (pct 10)
190 , div [] [ viewInput "text" "Enter your Phone number" model.phoneNumber PhoneEntered ] 200 , padding (px 20)
191 , div [] [ viewInput "text" "Enter Shipping address" (Maybe.withDefault "" model.address) AddressEntered ] 201 , Css.width (pct 30)
192 , div [] [ button [ onClick CreatePressed ] [ text "Create" ] ] 202 ]
193 , div [] 203 ]
204 [ div [ fieldPadding, css [ bigHeading ] ] [ text "Signup" ]
205 , div [ fieldPadding ] [ viewInput "text" "Username" model.username UserEntered ]
206 , div [ fieldPadding ] [ viewInput "password" "Password" model.password PassEntered ]
207 , div [ fieldPadding ] [ viewInput "text" "Email" model.emailId EmailEntered ]
208 , div [ fieldPadding ] [ viewInput "text" "Phone Number" model.phoneNumber PhoneEntered ]
209 , div [ fieldPadding ] [ viewInput "text" "Shipping Address" (Maybe.withDefault "" model.address) AddressEntered ]
210 , div
211 [ fieldPadding
212 , css [ textAlign center ]
213 ]
214 [ furbyButton
215 [ onClick CreatePressed ]
216 [ text "Create Account" ]
217 ]
218 , div [ fieldPadding ]
194 [ text "Already have a account? " 219 [ text "Already have a account? "
195 , a [ href "/login" ] [ text "Login >" ] 220 , a [ href "/login" ] [ text "Login >" ]
196 ] 221 ]
diff --git a/frontend/src/Styles.elm b/frontend/src/Styles.elm
new file mode 100644
index 0000000..36f2a81
--- /dev/null
+++ b/frontend/src/Styles.elm
@@ -0,0 +1,104 @@
1module Styles exposing (..)
2
3import Css exposing (..)
4import Html
5import Html.Styled exposing (..)
6import Html.Styled.Attributes exposing (..)
7import Html.Styled.Events exposing (..)
8
9
10type alias Theme =
11 { primary : Color
12 , secondary : Color
13 , bad : Color
14 , fg : Color
15 , bg : Color
16 , fgLight : Color
17 , bgLight : Color
18 }
19
20
21theme : Theme
22theme =
23 Theme
24 (hex "fedbd0")
25 -- primary
26 (hex "feeae6")
27 -- secondary
28 (hex "ff0000")
29 -- bad
30 (hex "442c2e")
31 -- fg
32 (hex "ffffff")
33 -- bg
34 (hex "442c2e")
35 -- fgLight
36 (hex "feeae6")
37
38
39
40-- bgLight
41
42
43headerLink : List (Attribute msg) -> List (Html msg) -> Html msg
44headerLink =
45 styled a
46 [ color theme.fgLight
47 , padding (px 12)
48 , textDecoration Css.none
49 , hover
50 [ backgroundColor theme.secondary
51 , textDecoration underline
52 ]
53 ]
54
55
56furbyButton : List (Attribute msg) -> List (Html msg) -> Html msg
57furbyButton =
58 styled button
59 [ margin (px 12)
60 , color theme.fg
61 , Css.height (px 40)
62 , border (px 0)
63 , padding2 (px 6) (px 12)
64 , backgroundColor theme.primary
65 , hover
66 [ backgroundColor theme.secondary
67 , color theme.fg
68 , margin (px 12)
69 ]
70 ]
71
72
73furbySelect : List (Attribute msg) -> List (Html msg) -> Html msg
74furbySelect =
75 styled select
76 [ margin (px 6)
77 , color theme.fg
78 , border (px 0)
79 , borderBottom3 (px 2) solid theme.bgLight
80 , textAlign right
81 , padding2 (px 3) (px 3)
82 , backgroundColor theme.bg
83 , hover
84 [ borderBottom3 (px 2) solid theme.fg
85 ]
86 ]
87
88
89loginInputField : List (Attribute msg) -> List (Html msg) -> Html msg
90loginInputField =
91 styled input
92 [ Css.width (pct 100)
93 , color theme.fg
94 , border (px 0)
95 , borderBottom3 (px 1) solid theme.bgLight
96 , focus
97 [ borderBottom3 (px 2) solid theme.fg
98 ]
99 ]
100
101
102bigHeading : Style
103bigHeading =
104 fontSize (px 24)
diff --git a/frontend/src/Utils.elm b/frontend/src/Utils.elm
index 825e4b7..b6c4bd5 100644
--- a/frontend/src/Utils.elm
+++ b/frontend/src/Utils.elm
@@ -1,5 +1,10 @@
1module Utils exposing (..) 1module Utils exposing (..)
2 2
3import Html
4import Html.Styled exposing (..)
5import Html.Styled.Attributes exposing (..)
6import Html.Styled.Events exposing (..)
7
3 8
4between : ( Float, Float ) -> Float -> Bool 9between : ( Float, Float ) -> Float -> Bool
5between ( l, u ) v = 10between ( l, u ) v =
@@ -13,3 +18,43 @@ range start stop step =
13 18
14 else 19 else
15 start :: range (start + step) stop step 20 start :: range (start + step) stop step
21
22
23modelViewer : List (Attribute msg) -> List (Html msg) -> Html msg
24modelViewer attributes children =
25 node "model-viewer" attributes children
26
27
28cameraControls : Attribute msg
29cameraControls =
30 attribute "camera-controls" ""
31
32
33autoRotate : Attribute msg
34autoRotate =
35 attribute "auto-rotate" ""
36
37
38ar : Attribute msg
39ar =
40 attribute "ar" ""
41
42
43arSrc : String -> Attribute msg
44arSrc src =
45 attribute "src" src
46
47
48arIosSrc : String -> Attribute msg
49arIosSrc src =
50 attribute "ios-src" src
51
52
53arModes : String -> Attribute msg
54arModes mode =
55 attribute "ar-modes" mode
56
57
58loading : String -> Attribute msg
59loading mode =
60 attribute "loading" mode