aboutsummaryrefslogtreecommitdiff
path: root/frontend/src/Profile.elm
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/src/Profile.elm')
-rw-r--r--frontend/src/Profile.elm211
1 files changed, 211 insertions, 0 deletions
diff --git a/frontend/src/Profile.elm b/frontend/src/Profile.elm
new file mode 100644
index 0000000..6575d41
--- /dev/null
+++ b/frontend/src/Profile.elm
@@ -0,0 +1,211 @@
1module Profile exposing (..)
2
3import Browser
4import Browser.Navigation as Nav
5import Css exposing (..)
6import Html
7import Html.Styled exposing (..)
8import Html.Styled.Attributes exposing (..)
9import Html.Styled.Events exposing (..)
10import Http
11import Icons exposing (..)
12import Json.Decode as D
13import Json.Encode as Encode
14import Styles exposing (..)
15import Utils exposing (..)
16
17
18emptyProfile =
19 UserProfile "" "" "" Nothing 0 []
20
21
22type alias Transaction =
23 { amount : Float
24 , transactionId : Int
25 , orderDate : String
26 , paymentMode : String
27 }
28
29
30type alias UserProfile =
31 { username : String
32 , phoneNumber : String
33 , emailId : String
34 , address : Maybe String
35 , ratingsGiven : Int
36 , transactions : List Transaction
37 }
38
39
40type alias Model =
41 { profile : UserProfile
42 , status : Status
43 }
44
45
46type Status
47 = Loading
48 | Loaded
49 | NotLoaded
50
51
52type Msg
53 = ProfileLoaded (Result Http.Error UserProfile)
54 | FetchProfile
55
56
57init : Model
58init =
59 Model emptyProfile NotLoaded
60
61
62update : Msg -> Model -> ( Model, Cmd Msg )
63update msg model =
64 case msg of
65 ProfileLoaded res ->
66 case res of
67 Ok p ->
68 ( { model | profile = p }, Cmd.none )
69
70 Err _ ->
71 ( { model | status = NotLoaded }, Cmd.none )
72
73 FetchProfile ->
74 ( { model | status = Loading }, tryFetchProfile )
75
76
77decodeProfile : D.Decoder UserProfile
78decodeProfile =
79 D.map6 UserProfile
80 (D.field "username" D.string)
81 (D.field "phone_number" D.string)
82 (D.field "email_id" D.string)
83 (D.field "address" (D.nullable D.string))
84 (D.field "ratings_given" D.int)
85 (D.field "transactions" (D.list decodeTransaction))
86
87
88decodeTransaction : D.Decoder Transaction
89decodeTransaction =
90 D.map4 Transaction
91 (D.field "amount" D.float)
92 (D.field "id" D.int)
93 (D.field "order_date" D.string)
94 (D.field "payment_type" D.string)
95
96
97tryFetchProfile : Cmd Msg
98tryFetchProfile =
99 let
100 _ =
101 Debug.log "err" <| "fetching user profile"
102 in
103 Http.riskyRequest
104 { method = "GET"
105 , headers = []
106 , url = "http://127.0.0.1:7878/user/profile"
107 , body = Http.emptyBody
108 , expect = Http.expectJson ProfileLoaded decodeProfile
109 , timeout = Nothing
110 , tracker = Nothing
111 }
112
113
114viewStatus : Status -> String
115viewStatus s =
116 case s of
117 Loading ->
118 "Loading"
119
120 Loaded ->
121 "Ready!"
122
123 NotLoaded ->
124 "Not loaded ..."
125
126
127viewTransactions : List Transaction -> Html Msg
128viewTransactions ts =
129 let
130 headings =
131 [ "Order ID", "Date", "Amount (₹)", "Payment Mode" ]
132 |> List.map (th [] << List.singleton << text)
133
134 transactionRow t =
135 List.map (td [] << List.singleton)
136 [ text <| String.fromInt t.transactionId
137 , text t.orderDate
138 , text <| String.fromFloat t.amount
139 , text t.paymentMode
140 ]
141 in
142 div []
143 [ div
144 [ css [ bigHeading, marginTop (px 20), marginBottom (px 12) ] ]
145 [ text "Transactions" ]
146 , Html.Styled.table
147 [ css
148 [ Css.width (pct 100)
149 , maxWidth (px 650)
150 ]
151 ]
152 ([ tr [ style "text-align" "right" ] headings
153 ]
154 ++ List.map (tr [ style "text-align" "right" ] << transactionRow) ts
155 )
156 ]
157
158
159profileField : String -> String -> Html Msg
160profileField fieldName entry =
161 div []
162 [ div
163 [ css
164 [ cardSecondaryText
165 , textTransform uppercase
166 , paddingBottom (px 3)
167 ]
168 ]
169 [ text fieldName ]
170 , div
171 [ css
172 [ cardPrimaryText
173 , paddingBottom (px 12)
174 ]
175 ]
176 [ text entry ]
177 ]
178
179
180viewProfile : UserProfile -> Html Msg
181viewProfile u =
182 div
183 []
184 [ div
185 [ css [ bigHeading, marginTop (px 20), marginBottom (px 12) ] ]
186 [ text "Profile" ]
187 , profileField "name" u.username
188 , profileField "email" u.emailId
189 , profileField "contact number" u.phoneNumber
190 , profileField "address" <| Maybe.withDefault "No address provided" u.address
191 , profileField "Total Reviews" <| String.fromInt u.ratingsGiven
192 , hr [] []
193 , viewTransactions u.transactions
194 ]
195
196
197view : Model -> Html Msg
198view model =
199 case model.status of
200 Loading ->
201 div [] [ text <| viewStatus Loading ]
202
203 _ ->
204 div
205 [ css
206 [ margin auto
207 , marginTop (pct 5)
208 , Css.width (pct 40)
209 ]
210 ]
211 [ viewProfile model.profile ]