diff options
author | Akshay <[email protected]> | 2020-12-24 05:21:40 +0000 |
---|---|---|
committer | Akshay <[email protected]> | 2020-12-24 05:21:40 +0000 |
commit | 9d2b6ee10ec5359cc91769d430485c8c869ba1a8 (patch) | |
tree | b2d541e575ab6e3f70cb709f156f06afca085881 /frontend/src/Cart.elm | |
parent | 7c65421328552b08e64df25e224fe9d54d363e6e (diff) |
monorepo
Diffstat (limited to 'frontend/src/Cart.elm')
-rw-r--r-- | frontend/src/Cart.elm | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/frontend/src/Cart.elm b/frontend/src/Cart.elm new file mode 100644 index 0000000..a1750f6 --- /dev/null +++ b/frontend/src/Cart.elm | |||
@@ -0,0 +1,164 @@ | |||
1 | module Cart exposing (..) | ||
2 | |||
3 | import Browser | ||
4 | import Browser.Navigation as Nav | ||
5 | import Html exposing (..) | ||
6 | import Html.Attributes exposing (..) | ||
7 | import Html.Events exposing (..) | ||
8 | import Http | ||
9 | import Json.Decode as D | ||
10 | import Json.Encode as Encode | ||
11 | import Url | ||
12 | import Url.Parser as P exposing ((</>), Parser, int, oneOf, s, string) | ||
13 | |||
14 | |||
15 | type alias Product = | ||
16 | { id : Int | ||
17 | , name : String | ||
18 | , kind : Maybe String | ||
19 | , price : Float | ||
20 | , description : Maybe String | ||
21 | } | ||
22 | |||
23 | |||
24 | type alias Model = | ||
25 | { pageStatus : Status | ||
26 | , products : List Product | ||
27 | } | ||
28 | |||
29 | |||
30 | type Status | ||
31 | = Loading | ||
32 | | Loaded | ||
33 | | NotLoaded | ||
34 | |||
35 | |||
36 | type Msg | ||
37 | = CartLoaded (Result Http.Error (List Product)) | ||
38 | | FetchCartItems | ||
39 | | RemoveFromCart Int | ||
40 | | CartItemRemoved (Result Http.Error ()) | ||
41 | |||
42 | |||
43 | init : Model | ||
44 | init = | ||
45 | Model NotLoaded [] | ||
46 | |||
47 | |||
48 | update : Msg -> Model -> ( Model, Cmd Msg ) | ||
49 | update msg model = | ||
50 | case msg of | ||
51 | CartLoaded res -> | ||
52 | case res of | ||
53 | Ok s -> | ||
54 | ( { model | products = s, pageStatus = Loaded }, Cmd.none ) | ||
55 | |||
56 | Err e -> | ||
57 | let | ||
58 | _ = | ||
59 | Debug.log "error" e | ||
60 | in | ||
61 | ( { model | pageStatus = NotLoaded }, Cmd.none ) | ||
62 | |||
63 | RemoveFromCart id -> | ||
64 | ( model, removeProduct id ) | ||
65 | |||
66 | CartItemRemoved _ -> | ||
67 | ( { model | pageStatus = Loading }, fetchCartItems ) | ||
68 | |||
69 | FetchCartItems -> | ||
70 | ( { model | pageStatus = Loading }, fetchCartItems ) | ||
71 | |||
72 | |||
73 | decodeProduct : D.Decoder Product | ||
74 | decodeProduct = | ||
75 | D.map5 Product | ||
76 | (D.field "id" D.int) | ||
77 | (D.field "name" D.string) | ||
78 | (D.field "kind" (D.nullable D.string)) | ||
79 | (D.field "price" D.float) | ||
80 | (D.field "description" (D.nullable D.string)) | ||
81 | |||
82 | |||
83 | decodeResponse : D.Decoder (List Product) | ||
84 | decodeResponse = | ||
85 | D.list decodeProduct | ||
86 | |||
87 | |||
88 | removeProduct : Int -> Cmd Msg | ||
89 | removeProduct id = | ||
90 | let | ||
91 | _ = | ||
92 | Debug.log "cart" "fetching cart items" | ||
93 | in | ||
94 | Http.riskyRequest | ||
95 | { method = "POST" | ||
96 | , headers = [] | ||
97 | , url = "http://127.0.0.1:7878/cart/remove" | ||
98 | , body = Http.stringBody "application/json" <| String.fromInt id | ||
99 | , expect = Http.expectWhatever CartItemRemoved | ||
100 | , timeout = Nothing | ||
101 | , tracker = Nothing | ||
102 | } | ||
103 | |||
104 | |||
105 | fetchCartItems : Cmd Msg | ||
106 | fetchCartItems = | ||
107 | let | ||
108 | _ = | ||
109 | Debug.log "cart" "fetching cart items" | ||
110 | in | ||
111 | Http.riskyRequest | ||
112 | { method = "GET" | ||
113 | , headers = [] | ||
114 | , url = "http://127.0.0.1:7878/cart/items" | ||
115 | , body = Http.emptyBody | ||
116 | , expect = Http.expectJson CartLoaded decodeResponse | ||
117 | , timeout = Nothing | ||
118 | , tracker = Nothing | ||
119 | } | ||
120 | |||
121 | |||
122 | viewStatus : Status -> String | ||
123 | viewStatus s = | ||
124 | case s of | ||
125 | Loading -> | ||
126 | "Loading" | ||
127 | |||
128 | Loaded -> | ||
129 | "Ready!" | ||
130 | |||
131 | NotLoaded -> | ||
132 | "Not loaded ..." | ||
133 | |||
134 | |||
135 | viewProduct : Product -> Html Msg | ||
136 | viewProduct p = | ||
137 | div [] | ||
138 | [ text p.name | ||
139 | , div [] [ text <| Maybe.withDefault "" p.kind ] | ||
140 | , div [] [ text <| Maybe.withDefault "" p.description ] | ||
141 | , div [] [ text <| String.fromFloat p.price ] | ||
142 | , div [] [ button [ onClick (RemoveFromCart p.id) ] [ text "Remove" ] ] | ||
143 | , div [] [ a [ href ("/product/" ++ String.fromInt p.id) ] [ text "View Product" ] ] | ||
144 | ] | ||
145 | |||
146 | |||
147 | view : Model -> Html Msg | ||
148 | view model = | ||
149 | case model.pageStatus of | ||
150 | Loading -> | ||
151 | div [] [ text <| viewStatus Loading ] | ||
152 | |||
153 | _ -> | ||
154 | div [] | ||
155 | [ let | ||
156 | cart = | ||
157 | List.map viewProduct model.products | ||
158 | in | ||
159 | if List.isEmpty cart then | ||
160 | text "No items in cart" | ||
161 | |||
162 | else | ||
163 | ul [] cart | ||
164 | ] | ||