diff options
Diffstat (limited to 'frontend/src/Catalog.elm')
-rw-r--r-- | frontend/src/Catalog.elm | 100 |
1 files changed, 86 insertions, 14 deletions
diff --git a/frontend/src/Catalog.elm b/frontend/src/Catalog.elm index 5b233f2..7e9bde7 100644 --- a/frontend/src/Catalog.elm +++ b/frontend/src/Catalog.elm | |||
@@ -27,6 +27,8 @@ type alias Product = | |||
27 | , price : Float | 27 | , price : Float |
28 | , description : Maybe String | 28 | , description : Maybe String |
29 | , averageRating : Maybe Float | 29 | , averageRating : Maybe Float |
30 | , src : String | ||
31 | , iosSrc : String | ||
30 | } | 32 | } |
31 | 33 | ||
32 | 34 | ||
@@ -129,13 +131,15 @@ update msg model = | |||
129 | 131 | ||
130 | decodeProduct : D.Decoder Product | 132 | decodeProduct : D.Decoder Product |
131 | decodeProduct = | 133 | decodeProduct = |
132 | D.map6 Product | 134 | D.map8 Product |
133 | (D.field "id" D.int) | 135 | (D.field "id" D.int) |
134 | (D.field "name" D.string) | 136 | (D.field "name" D.string) |
135 | (D.field "kind" (D.nullable D.string)) | 137 | (D.field "kind" (D.nullable D.string)) |
136 | (D.field "price" D.float) | 138 | (D.field "price" D.float) |
137 | (D.field "description" (D.nullable D.string)) | 139 | (D.field "description" (D.nullable D.string)) |
138 | (D.field "average_rating" (D.nullable D.float)) | 140 | (D.field "average_rating" (D.nullable D.float)) |
141 | (D.field "src" D.string) | ||
142 | (D.field "ios_src" D.string) | ||
139 | 143 | ||
140 | 144 | ||
141 | decodeResponse : D.Decoder (List Product) | 145 | decodeResponse : D.Decoder (List Product) |
@@ -170,18 +174,83 @@ viewStatus s = | |||
170 | 174 | ||
171 | viewProduct : Product -> Html Msg | 175 | viewProduct : Product -> Html Msg |
172 | viewProduct p = | 176 | viewProduct p = |
173 | div [] | 177 | div |
174 | [ div [] [ text p.name ] | 178 | [ css |
175 | , div [] [ text <| Maybe.withDefault "" p.kind ] | 179 | [ marginBottom (px 20) |
176 | , div [] [ text <| Maybe.withDefault "" p.description ] | 180 | , border3 (px 1) solid theme.primary |
177 | , div [] [ text <| String.fromFloat p.price ] | 181 | , borderRadius (px 4) |
178 | , case p.averageRating of | 182 | , padding (px 20) |
179 | Just v -> | 183 | , Css.width (pct 100) |
180 | text <| "Avg Rating: " ++ String.fromFloat v | 184 | , maxWidth (px 650) |
181 | 185 | ] | |
182 | Nothing -> | 186 | ] |
183 | text "No Ratings" | 187 | [ div |
184 | , div [] [ a [ href ("/product/" ++ String.fromInt p.id) ] [ text "View Product" ] ] | 188 | [ css |
189 | [ float left | ||
190 | , Css.width (pct 50) | ||
191 | ] | ||
192 | ] | ||
193 | [ modelViewer | ||
194 | [ cameraControls | ||
195 | , autoRotate | ||
196 | , arSrc p.src | ||
197 | , arIosSrc p.iosSrc | ||
198 | , loading "eager" | ||
199 | , arModes "webxr" | ||
200 | ] | ||
201 | [] | ||
202 | ] | ||
203 | , div | ||
204 | [ css | ||
205 | [ float left | ||
206 | , Css.width (pct 50) | ||
207 | ] | ||
208 | ] | ||
209 | [ div | ||
210 | [ css | ||
211 | [ cardSecondaryText | ||
212 | , paddingBottom (px 3) | ||
213 | , fontVariant smallCaps | ||
214 | ] | ||
215 | ] | ||
216 | [ text <| Maybe.withDefault "" p.kind ] | ||
217 | , div | ||
218 | [ css | ||
219 | [ cardPrimaryText | ||
220 | , paddingBottom (px 3) | ||
221 | ] | ||
222 | ] | ||
223 | [ a [ href ("/product/" ++ String.fromInt p.id) ] [ text p.name ] ] | ||
224 | , div | ||
225 | [ css | ||
226 | [ cardSecondaryText | ||
227 | , paddingBottom (px 12) | ||
228 | ] | ||
229 | ] | ||
230 | [ case p.averageRating of | ||
231 | Just v -> | ||
232 | text <| "Avg Rating: " ++ String.fromFloat v | ||
233 | |||
234 | Nothing -> | ||
235 | text "No Ratings" | ||
236 | ] | ||
237 | , div | ||
238 | [ css | ||
239 | [ cardSupportingText | ||
240 | , paddingBottom (px 6) | ||
241 | ] | ||
242 | ] | ||
243 | [ text <| Maybe.withDefault "No description provided" p.description ] | ||
244 | , div | ||
245 | [ css | ||
246 | [ fontWeight bold | ||
247 | , fontSize (px 14) | ||
248 | , money | ||
249 | ] | ||
250 | ] | ||
251 | [ text <| String.fromFloat p.price ] | ||
252 | ] | ||
253 | , div [ style "clear" "both" ] [] | ||
185 | ] | 254 | ] |
186 | 255 | ||
187 | 256 | ||
@@ -260,7 +329,10 @@ view model = | |||
260 | ] | 329 | ] |
261 | [ div [ css [ bigHeading ] ] [ text "Products" ] | 330 | [ div [ css [ bigHeading ] ] [ text "Products" ] |
262 | , ul | 331 | , ul |
263 | [ css [ padding (px 0) ] | 332 | [ css |
333 | [ padding (px 0) | ||
334 | , listStyle Css.none | ||
335 | ] | ||
264 | ] | 336 | ] |
265 | (filterProducts model |> List.map viewProduct) | 337 | (filterProducts model |> List.map viewProduct) |
266 | ] | 338 | ] |