Commit 1530ca76 authored by Karen Konou's avatar Karen Konou

[WIP] [User] Image upload API functions

parent 35381e2c
Pipeline #3191 failed with stage
in 0 seconds
......@@ -25,7 +25,8 @@ type UserInfo
, ui_cwRole :: Maybe String
, ui_cwTouchPhone :: Maybe String
, ui_cwTouchMail :: Maybe String
, ui_cwDescription :: Maybe String }
, ui_cwDescription :: Maybe String
, ui_cwImagePath :: Maybe String }
type UserInfoM
= { token :: NotNull String
, ui_id :: NotNull Int
......@@ -43,7 +44,8 @@ type UserInfoM
, ui_cwRole :: String
, ui_cwTouchPhone :: String
, ui_cwTouchMail :: String
, ui_cwDescription :: String }
, ui_cwDescription :: String
, ui_cwImagePath :: String }
userInfoQuery = { user_infos: { user_id: Var :: _ "id" Int } =>>
{ ui_id: unit
......@@ -61,7 +63,8 @@ userInfoQuery = { user_infos: { user_id: Var :: _ "id" Int } =>>
, ui_cwRole: unit
, ui_cwTouchMail: unit
, ui_cwTouchPhone: unit
, ui_cwDescription: unit }
, ui_cwDescription: unit
, ui_cwImagePath: unit }
}
_ui_cwFirstName :: Lens' UserInfo String
......@@ -128,9 +131,15 @@ _ui_cwTouchPhone = lens getter setter
_ui_cwDescription :: Lens' UserInfo String
_ui_cwDescription = lens getter setter
where
getter ({ui_cwDescription: val}) = fromMaybe "" val
getter ({ ui_cwDescription: val }) = fromMaybe "" val
setter ui val = ui { ui_cwDescription = Just val }
_ui_cwImagePath :: Lens' UserInfo String
_ui_cwImagePath = lens getter setter
where
getter ({ ui_cwImagePath: val }) = fromMaybe "" val
setter ui val = ui { ui_cwImagePath = Just val }
type User
= { u_id :: Int
, u_hyperdata ::
......
"use strict";
exports.handleRef = handleRef;
function handleRef(ref) {
return ref.current.files[0]
};
\ No newline at end of file
......@@ -7,9 +7,12 @@ module Gargantext.Components.Nodes.Annuaire.User
import Gargantext.Prelude
import DOM.Simple as DOM
import DOM.Simple.Event as DE
import Data.Either (Either(..))
import Data.Lens as L
import Data.Maybe (Maybe(..), fromMaybe)
import Data.Nullable (Nullable, null)
import Effect (Effect)
import Effect.Aff (launchAff_)
import Effect.Class (liftEffect)
......@@ -21,11 +24,11 @@ import Gargantext.Components.InputWithEnter (inputWithEnter)
import Gargantext.Components.Nodes.Annuaire.Tabs as Tabs
import Gargantext.Components.Nodes.Annuaire.User.Contacts.Types (Contact(..), ContactData, ContactTouch(..), ContactWhere(..), ContactWho(..), HyperdataContact(..), HyperdataUser(..), _city, _country, _firstName, _labTeamDeptsJoinComma, _lastName, _mail, _office, _organizationJoinComma, _ouFirst, _phone, _role, _shared, _touch, _who, defaultContactTouch, defaultContactWhere, defaultContactWho, defaultHyperdataContact, defaultHyperdataUser)
import Gargantext.Components.Nodes.Lists.Types as LT
import Gargantext.Config.REST (AffRESTError, logRESTError)
import Gargantext.Config.REST (AffRESTError, RESTError, logRESTError)
import Gargantext.Config.Utils (handleRESTError)
import Gargantext.Ends (Frontends)
import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Sessions (Session(..), WithSession, WithSessionContext, sessionId)
import Gargantext.Sessions (Session(..), WithSession, WithSessionContext, postMultipart, sessionId, sessionUrl)
import Gargantext.Types (FrontendError)
import Gargantext.Utils.Reactix as R2
import Gargantext.Utils.Toestand as T2
......@@ -36,17 +39,21 @@ import Reactix.DOM.HTML as H
import Record as Record
import Toestand as T
foreign import handleRef :: R.Ref (Nullable DOM.Element) -> String
here :: R2.Here
here = R2.here "Gargantext.Components.Nodes.Annuaire.User"
type DisplayProps = ( title :: String )
type DisplayProps = ( title :: String, image :: String, session :: Session)
display :: R2.Component DisplayProps
display = R.createElement displayCpt
displayCpt :: R.Component DisplayProps
displayCpt = here.component "display" cpt
where
cpt { title } children = do
cpt { title, image, session } children = do
fileRef <- R.useRef null
pure $ H.div { className: "container-fluid" }
[ H.div { className: "row", id: "contact-page-header" }
[ H.div { className: "col-md-6"} [ H.h3 {} [ H.text title ] ]
......@@ -57,11 +64,11 @@ displayCpt = here.component "display" cpt
[ H.div { className: "col-md-12" }
[ H.div { className: "row" }
[ H.div { className: "col-md-2" } [ H.div { className: "container-fluid" }
[ H.div { className: "row" } [ H.img { src: "/images/Gargantextuel-212x300.jpg"} ]
, H.form { className: "row", enctype: "multipart/form-data" }
[ H.div { className: "row" } [ H.img { src: image} ]
, H.form { on: {submit: onSubmit session fileRef}, className: "row", encType: "multipart/form-data" }
[ H.label { for: "avatar" } [H.text "Choose your profile picture:"]
, H.input { type: "file", id: "avatar", accept: "image/png, image/jpeg" }
, H.button {} [ H.text "save" ]
, H.input { type: "file", ref: fileRef, accept: "image/png, image/jpeg" }
, H.button { className: "btn btn-secondary" } [ H.text "save" ]
]
]
]
......@@ -71,6 +78,14 @@ displayCpt = here.component "display" cpt
]
]
]
where
onSubmit :: Session -> R.Ref (Nullable DOM.Element) -> DE.Event -> Effect Unit
onSubmit session fileRef e = do
let body = handleRef fileRef
R2.preventDefault e
launchAff_ $ do
aff :: Either RESTError Int <- postMultipart session "image" body
pure aff
{-
listElement :: Array R.Element -> R.Element
......@@ -116,9 +131,9 @@ userLayoutWithKeyCpt = here.component "userLayoutWithKey" cpt where
useLoader { errorHandler
, loader: getUserInfoWithReload
, path: { nodeId: userId, reload: reload', session }
, render: \userInfo@{ ui_username } ->
, render: \userInfo@{ ui_username, ui_cwImagePath} ->
H.ul { className: "col-md-12 list-group" } [
display { title: fromMaybe "no name" (Just ui_username) }
display { session, title: fromMaybe "no name" (Just ui_username), image: fromMaybe "/images/Gargantextuel-212x300.jpg" ui_cwImagePath}
(contactInfos userInfo (onUpdateUserInfo boxes.errors reload))
, Tabs.tabs {
boxes
......
-- | A module for authenticating to create sessions and handling them
module Gargantext.Sessions
( module Gargantext.Sessions.Types
, WithSession, WithSessionContext
, load, change
, Action(..), act, delete, get, post, put, put_
, postAuthRequest, postForgotPasswordRequest
, deleteWithBody, postWwwUrlencoded
, getCacheState, setCacheState
) where
( Action(..)
, WithSession
, WithSessionContext
, act
, change
, delete
, deleteWithBody
, get
, getCacheState
, load
, module Gargantext.Sessions.Types
, post
, postAuthRequest
, postForgotPasswordRequest
, postMultipart
, postWwwUrlencoded
, put
, put_
, setCacheState
)
where
import Gargantext.Prelude
import DOM.Simple.Console (log2)
import Data.Either (Either(..), hush)
......@@ -15,19 +30,16 @@ import Data.Map as Map
import Data.Maybe (Maybe(..), fromMaybe)
import Effect (Effect)
import Effect.Aff (Aff)
import Reactix as R
import Simple.JSON as JSON
import Toestand as T
import Web.Storage.Storage (getItem, removeItem, setItem)
import Gargantext.Prelude
import Gargantext.Components.Login.Types (AuthData(..), AuthInvalid(..), AuthRequest(..), AuthResponse(..))
import Gargantext.Components.Nodes.Lists.Types as NT
import Gargantext.Config.REST as REST
import Gargantext.Ends (class ToUrl, Backend, toUrl)
import Gargantext.Sessions.Types (Session(..), Sessions(..), OpenNodes, NodeId, mkNodeId, sessionUrl, sessionId, empty, null, unSessions, lookup, cons, tryCons, update, remove, tryRemove)
import Gargantext.Utils.Reactix as R2
import Reactix as R
import Simple.JSON as JSON
import Toestand as T
import Web.Storage.Storage (getItem, removeItem, setItem)
type WithSession c =
( session :: Session
......@@ -157,3 +169,7 @@ post session@(Session {token}) p = REST.post (Just token) (toUrl session p)
postWwwUrlencoded :: forall b p. JSON.ReadForeign b => ToUrl Session p =>
Session -> p -> REST.FormDataParams -> REST.AffRESTError b
postWwwUrlencoded session@(Session {token}) p = REST.postWwwUrlencoded (Just token) (toUrl session p)
postMultipart :: forall b p. JSON.ReadForeign b => ToUrl Session p =>
Session -> p -> String -> REST.AffRESTError b
postMultipart session@(Session {token}) p = REST.postMultipartFormData (Just token) (toUrl session p)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment