aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--frontend/src/Cart.elm4
-rw-r--r--frontend/src/Catalog.elm89
-rw-r--r--frontend/src/Login.elm2
-rw-r--r--frontend/src/Main.elm31
-rw-r--r--frontend/src/Product.elm24
-rw-r--r--frontend/src/Signup.elm2
-rw-r--r--frontend/src/Styles.elm15
-rw-r--r--frontend/src/Utils.elm5
8 files changed, 128 insertions, 44 deletions
diff --git a/frontend/src/Cart.elm b/frontend/src/Cart.elm
index 4f4cbef..f4697a8 100644
--- a/frontend/src/Cart.elm
+++ b/frontend/src/Cart.elm
@@ -193,7 +193,7 @@ viewCartItemListing listing =
193 -- , div [] [ a [ href ("/product/" ++ String.fromInt listing.productItem.id) ] [ text "View Product" ] ] 193 -- , div [] [ a [ href ("/product/" ++ String.fromInt listing.productItem.id) ] [ text "View Product" ] ]
194 -- ] 194 -- ]
195 tr [] 195 tr []
196 [ td [] [ a [ href ("/product/" ++ String.fromInt listing.productItem.id) ] [ text listing.productItem.name ] ] 196 [ td [] [ furbyLink [ href ("/product/" ++ String.fromInt listing.productItem.id) ] [ text listing.productItem.name ] ]
197 , td [] [ text <| String.fromFloat listing.productItem.price ] 197 , td [] [ text <| String.fromFloat listing.productItem.price ]
198 , td [] 198 , td []
199 [ furbyButton [ onClick (RemoveFromCart listing.productItem.id) ] [ div [ style "font-family" "monospace" ] [ text "-" ] ] 199 [ furbyButton [ onClick (RemoveFromCart listing.productItem.id) ] [ div [ style "font-family" "monospace" ] [ text "-" ] ]
@@ -250,6 +250,6 @@ view model =
250 [ css [ textAlign right ] ] 250 [ css [ textAlign right ] ]
251 [ furbyButton 251 [ furbyButton
252 [] 252 []
253 [ a [ href "/checkout" ] [ text "Checkout" ] ] 253 [ furbyLink [ href "/checkout" ] [ text "Checkout" ] ]
254 ] 254 ]
255 ] 255 ]
diff --git a/frontend/src/Catalog.elm b/frontend/src/Catalog.elm
index d4cbf96..666245e 100644
--- a/frontend/src/Catalog.elm
+++ b/frontend/src/Catalog.elm
@@ -10,6 +10,7 @@ import Html.Styled.Events exposing (..)
10import Http 10import Http
11import Json.Decode as D 11import Json.Decode as D
12import Json.Encode as Encode 12import Json.Encode as Encode
13import Set
13import Styles exposing (..) 14import Styles exposing (..)
14import Tuple exposing (..) 15import Tuple exposing (..)
15import Utils exposing (..) 16import Utils exposing (..)
@@ -35,12 +36,13 @@ type alias Product =
35type alias Filters = 36type alias Filters =
36 { price : ( Float, Float ) 37 { price : ( Float, Float )
37 , rating : ( Float, Float ) 38 , rating : ( Float, Float )
39 , kinds : Set.Set String
38 } 40 }
39 41
40 42
41defaultFilters : Filters 43defaultFilters : Filters
42defaultFilters = 44defaultFilters =
43 Filters ( -1, 100000 ) ( 0, 5 ) 45 Filters ( -1, 100000 ) ( 0, 5 ) (Set.fromList [ "Chair", "Sofa", "Bed", "Table", "Lamp" ])
44 46
45 47
46type alias Model = 48type alias Model =
@@ -63,6 +65,7 @@ type Msg
63 | ChangePriceUpper Float 65 | ChangePriceUpper Float
64 | ChangeRatingLower Float 66 | ChangeRatingLower Float
65 | ChangeRatingUpper Float 67 | ChangeRatingUpper Float
68 | FilterCheck String Bool
66 69
67 70
68init : Model 71init : Model
@@ -128,6 +131,28 @@ update msg model =
128 in 131 in
129 ( { model | filters = nfs }, Cmd.none ) 132 ( { model | filters = nfs }, Cmd.none )
130 133
134 FilterCheck field val ->
135 case val of
136 True ->
137 let
138 fs =
139 model.filters
140
141 nfs =
142 { fs | kinds = Set.insert field fs.kinds }
143 in
144 ( { model | filters = nfs }, Cmd.none )
145
146 False ->
147 let
148 fs =
149 model.filters
150
151 nfs =
152 { fs | kinds = Set.remove field fs.kinds }
153 in
154 ( { model | filters = nfs }, Cmd.none )
155
131 156
132decodeProduct : D.Decoder Product 157decodeProduct : D.Decoder Product
133decodeProduct = 158decodeProduct =
@@ -181,13 +206,13 @@ viewProduct p =
181 , borderRadius (px 4) 206 , borderRadius (px 4)
182 , padding (px 20) 207 , padding (px 20)
183 , Css.width (pct 100) 208 , Css.width (pct 100)
184 , maxWidth (px 650) 209 , maxWidth (px 350)
185 ] 210 ]
186 ] 211 ]
187 [ div 212 [ div
188 [ css 213 [ css
189 [ float left 214 [ Css.width (pct 100)
190 , Css.width (pct 50) 215 , Css.height (px 350)
191 ] 216 ]
192 ] 217 ]
193 [ modelViewer 218 [ modelViewer
@@ -197,13 +222,13 @@ viewProduct p =
197 , arIosSrc p.iosSrc 222 , arIosSrc p.iosSrc
198 , loading "eager" 223 , loading "eager"
199 , arModes "webxr" 224 , arModes "webxr"
225 , css [ Css.width (pct 100), Css.height (pct 100) ]
200 ] 226 ]
201 [] 227 []
202 ] 228 ]
203 , div 229 , div
204 [ css 230 [ css
205 [ float left 231 [ Css.width (pct 100)
206 , Css.width (pct 50)
207 ] 232 ]
208 ] 233 ]
209 [ div 234 [ div
@@ -220,7 +245,7 @@ viewProduct p =
220 , paddingBottom (px 3) 245 , paddingBottom (px 3)
221 ] 246 ]
222 ] 247 ]
223 [ a [ href ("/product/" ++ String.fromInt p.id) ] [ text p.name ] ] 248 [ furbyLink [ href ("/product/" ++ String.fromInt p.id) ] [ text p.name ] ]
224 , div 249 , div
225 [ css 250 [ css
226 [ cardSecondaryText 251 [ cardSecondaryText
@@ -274,22 +299,57 @@ viewFilters model =
274 [ div 299 [ div
275 [ css 300 [ css
276 [ bigHeading 301 [ bigHeading
277 , paddingBottom (px 12) 302 , paddingBottom (px 18)
278 ] 303 ]
279 ] 304 ]
280 [ text "Filters" ] 305 [ text "Filters" ]
281 , div [] 306 , div
307 [ css
308 [ paddingBottom (px 12)
309 ]
310 ]
282 [ div [] [ text "Price" ] 311 [ div [] [ text "Price" ]
283 , furbySelect [ onInput (ChangePriceLower << inp), style "appearance" "none" ] (viewRange 0 priceRange) 312 , furbySelect [ onInput (ChangePriceLower << inp), style "appearance" "none" ] (viewRange 0 priceRange)
284 , text "to" 313 , text "to"
285 , furbySelect [ onInput (ChangePriceUpper << inp), style "appearance" "none" ] (viewRange 50000 priceRange) 314 , furbySelect [ onInput (ChangePriceUpper << inp), style "appearance" "none" ] (viewRange 50000 priceRange)
286 ] 315 ]
287 , div [] 316 , div
317 [ css
318 [ paddingBottom (px 12)
319 ]
320 ]
288 [ div [] [ text "Rating" ] 321 [ div [] [ text "Rating" ]
289 , furbySelect [ onInput (ChangeRatingLower << inp), style "appearance" "none" ] (viewRange 1 ratingRange) 322 , furbySelect [ onInput (ChangeRatingLower << inp), style "appearance" "none" ] (viewRange 1 ratingRange)
290 , text "to" 323 , text "to"
291 , furbySelect [ onInput (ChangeRatingUpper << inp), style "appearance" "none" ] (viewRange 5 ratingRange) 324 , furbySelect [ onInput (ChangeRatingUpper << inp), style "appearance" "none" ] (viewRange 5 ratingRange)
292 ] 325 ]
326 , let
327 kinds =
328 [ "Chair", "Sofa", "Bed", "Table", "Lamp" ]
329 in
330 div []
331 ([ div
332 [ css
333 [ paddingBottom (px 12)
334 ]
335 ]
336 [ text "Furniture Kind" ]
337 ]
338 ++ List.map
339 (\k ->
340 div
341 []
342 [ input
343 [ type_ "checkbox"
344 , onCheck (FilterCheck k)
345 , Html.Styled.Attributes.checked (Set.member k model.filters.kinds)
346 ]
347 []
348 , text k
349 ]
350 )
351 kinds
352 )
293 ] 353 ]
294 354
295 355
@@ -297,6 +357,7 @@ filterProducts : Model -> List Product
297filterProducts model = 357filterProducts model =
298 model.products 358 model.products
299 |> List.filter (between model.filters.price << .price) 359 |> List.filter (between model.filters.price << .price)
360 |> List.filter (flip Set.member model.filters.kinds << Maybe.withDefault "Chair" << .kind)
300 |> List.filter 361 |> List.filter
301 (\p -> 362 (\p ->
302 p.averageRating 363 p.averageRating
@@ -328,11 +389,9 @@ view model =
328 ] 389 ]
329 ] 390 ]
330 [ div [ css [ bigHeading ] ] [ text "Products" ] 391 [ div [ css [ bigHeading ] ] [ text "Products" ]
331 , ul 392 , div
332 [ css 393 [ style "display" "grid"
333 [ padding (px 0) 394 , style "grid-template-columns" "auto auto auto"
334 , listStyle Css.none
335 ]
336 ] 395 ]
337 (filterProducts model |> List.map viewProduct) 396 (filterProducts model |> List.map viewProduct)
338 ] 397 ]
diff --git a/frontend/src/Login.elm b/frontend/src/Login.elm
index 87657bb..92a894f 100644
--- a/frontend/src/Login.elm
+++ b/frontend/src/Login.elm
@@ -134,5 +134,5 @@ view model =
134 , div [ fieldPadding ] [ viewInput "password" "Password" model.password PassEntered ] 134 , div [ fieldPadding ] [ viewInput "password" "Password" model.password PassEntered ]
135 , div [ css [ textAlign center ], fieldPadding ] [ furbyButton [ onClick LoginPressed ] [ text "Login" ] ] 135 , div [ css [ textAlign center ], fieldPadding ] [ furbyButton [ onClick LoginPressed ] [ text "Login" ] ]
136 , div [ css [ textAlign center ] ] [ text (viewStatus model.loginStatus) ] 136 , div [ css [ textAlign center ] ] [ text (viewStatus model.loginStatus) ]
137 , div [ fieldPadding ] [ text "Don't have an account? ", a [ href "/signup" ] [ text "Register now!" ] ] 137 , div [ fieldPadding ] [ text "Don't have an account? ", furbyLink [ href "/signup" ] [ text "Register now!" ] ]
138 ] 138 ]
diff --git a/frontend/src/Main.elm b/frontend/src/Main.elm
index 09a851d..07b029d 100644
--- a/frontend/src/Main.elm
+++ b/frontend/src/Main.elm
@@ -315,23 +315,24 @@ view model =
315 HomePage -> 315 HomePage ->
316 { title = "Login" 316 { title = "Login"
317 , body = 317 , body =
318 -- model.loginModel 318 model.loginModel
319 -- |> Login.view 319 |> Login.view
320 -- |> Html.Styled.map LoginMessage 320 |> Html.Styled.map LoginMessage
321 -- |> toUnstyled
322 -- |> List.singleton
323 div []
324 [ ul []
325 (List.map
326 (\l ->
327 li []
328 [ a [ href l ] [ text l ] ]
329 )
330 [ "/login", "/catalog", "/cart" ]
331 )
332 ]
333 |> toUnstyled 321 |> toUnstyled
334 |> List.singleton 322 |> List.singleton
323
324 --div []
325 -- [ ul []
326 -- (List.map
327 -- (\l ->
328 -- li []
329 -- [ a [ href l ] [ text l ] ]
330 -- )
331 -- [ "/login", "/catalog", "/cart" ]
332 -- )
333 -- ]
334 -- |> toUnstyled
335 -- |> List.singleton
335 } 336 }
336 337
337 LoginPage -> 338 LoginPage ->
diff --git a/frontend/src/Product.elm b/frontend/src/Product.elm
index 964538b..bedb22d 100644
--- a/frontend/src/Product.elm
+++ b/frontend/src/Product.elm
@@ -257,7 +257,7 @@ viewProduct p =
257 div 257 div
258 [ css 258 [ css
259 [ marginBottom (px 20) 259 [ marginBottom (px 20)
260 , padding (px 20) 260 , paddingTop (px 20)
261 , Css.width (pct 100) 261 , Css.width (pct 100)
262 ] 262 ]
263 ] 263 ]
@@ -265,6 +265,7 @@ viewProduct p =
265 [ css 265 [ css
266 [ float left 266 [ float left
267 , Css.width (pct 50) 267 , Css.width (pct 50)
268 , Css.height (px 400)
268 ] 269 ]
269 ] 270 ]
270 [ modelViewer 271 [ modelViewer
@@ -274,6 +275,7 @@ viewProduct p =
274 , arIosSrc p.iosSrc 275 , arIosSrc p.iosSrc
275 , loading "eager" 276 , loading "eager"
276 , arModes "webxr" 277 , arModes "webxr"
278 , css [ Css.height (pct 100), Css.width (pct 100) ]
277 ] 279 ]
278 [] 280 []
279 ] 281 ]
@@ -312,12 +314,11 @@ viewProduct p =
312 , money 314 , money
313 ] 315 ]
314 ] 316 ]
315 [ text <| String.fromFloat p.price 317 [ text <| String.fromFloat p.price ]
316 , div []
317 [ furbyButton [ onClick AddToCartPressed ] [ text "Add To Cart" ]
318 ]
319 ]
320 ] 318 ]
319 , div
320 [ css [ textAlign center, float bottom ] ]
321 [ furbyButton [ onClick AddToCartPressed, style "width" "100%" ] [ text "Add To Cart" ] ]
321 , div [ style "clear" "both" ] [] 322 , div [ style "clear" "both" ] []
322 ] 323 ]
323 324
@@ -377,7 +378,7 @@ viewInput t p v toMsg =
377 , placeholder p 378 , placeholder p
378 , value v 379 , value v
379 , onInput toMsg 380 , onInput toMsg
380 , css [ Css.width (pct 100), Css.height (px 100) ] 381 , css [ Css.width (pct 100) ]
381 ] 382 ]
382 [] 383 []
383 384
@@ -457,7 +458,14 @@ view model =
457 [ viewStars model 458 [ viewStars model
458 , div 459 , div
459 [] 460 []
460 [ viewInput "textarea" "Enter Comment Text" model.ratingText AddRatingComment ] 461 [ textarea
462 [ onInput AddRatingComment
463 , rows 5
464 , placeholder "Enter comment text"
465 , css [ Css.width (pct 100) ]
466 ]
467 [ text model.ratingText ]
468 ]
461 , div 469 , div
462 [ css 470 [ css
463 [ textAlign center ] 471 [ textAlign center ]
diff --git a/frontend/src/Signup.elm b/frontend/src/Signup.elm
index 028af9c..64c744e 100644
--- a/frontend/src/Signup.elm
+++ b/frontend/src/Signup.elm
@@ -217,7 +217,7 @@ view model =
217 ] 217 ]
218 , div [ fieldPadding ] 218 , div [ fieldPadding ]
219 [ text "Already have a account? " 219 [ text "Already have a account? "
220 , a [ href "/login" ] [ text "Login >" ] 220 , furbyLink [ href "/login" ] [ text "Login >" ]
221 ] 221 ]
222 , text (viewStatus model.status) 222 , text (viewStatus model.status)
223 ] 223 ]
diff --git a/frontend/src/Styles.elm b/frontend/src/Styles.elm
index 4222024..08cd6f3 100644
--- a/frontend/src/Styles.elm
+++ b/frontend/src/Styles.elm
@@ -47,8 +47,7 @@ headerLink =
47 , padding (px 12) 47 , padding (px 12)
48 , textDecoration Css.none 48 , textDecoration Css.none
49 , hover 49 , hover
50 [ backgroundColor theme.secondary 50 [ textDecoration underline
51 , textDecoration underline
52 ] 51 ]
53 ] 52 ]
54 53
@@ -71,6 +70,17 @@ furbyButton =
71 ] 70 ]
72 71
73 72
73furbyLink : List (Attribute msg) -> List (Html msg) -> Html msg
74furbyLink =
75 styled a
76 [ color theme.fgLight
77 , textDecoration Css.none
78 , hover
79 [ backgroundColor theme.secondary
80 ]
81 ]
82
83
74furbyRadio : String -> msg -> Html msg 84furbyRadio : String -> msg -> Html msg
75furbyRadio value msg = 85furbyRadio value msg =
76 label 86 label
@@ -108,6 +118,7 @@ loginInputField =
108 , color theme.fg 118 , color theme.fg
109 , border (px 0) 119 , border (px 0)
110 , borderBottom3 (px 1) solid theme.bgLight 120 , borderBottom3 (px 1) solid theme.bgLight
121 , outline Css.none
111 , focus 122 , focus
112 [ borderBottom3 (px 2) solid theme.fg 123 [ borderBottom3 (px 2) solid theme.fg
113 ] 124 ]
diff --git a/frontend/src/Utils.elm b/frontend/src/Utils.elm
index b6c4bd5..3a308ca 100644
--- a/frontend/src/Utils.elm
+++ b/frontend/src/Utils.elm
@@ -11,6 +11,11 @@ between ( l, u ) v =
11 v >= l && v <= u 11 v >= l && v <= u
12 12
13 13
14flip : (a -> b -> c) -> (b -> a -> c)
15flip f =
16 \b a -> f a b
17
18
14range : Int -> Int -> Int -> List Int 19range : Int -> Int -> Int -> List Int
15range start stop step = 20range start stop step =
16 if start >= stop then 21 if start >= stop then