index.js 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. const getGQL = url =>
  2. (query, variables={}) => fetch(url, {
  3. method: 'POST',
  4. headers: {
  5. "Content-Type": "application/json",
  6. ...(localStorage.authToken ? {Authorization: "Bearer " + localStorage.authToken } : {})
  7. },
  8. body: JSON.stringify({query, variables})
  9. }).then(res => res.json())
  10. export const actionPending = name => ({type: 'PROMISE', status: 'PENDING', name})
  11. export const actionResolved = (name, payload) => ({type: 'PROMISE', status: 'RESOLVED', name, payload})
  12. export const actionRejected = (name, error) => ({type: 'PROMISE', status: 'REJECTED', name, error})
  13. let shopGQL = getGQL('/graphql')
  14. export const actionPromise = (name, promise) =>
  15. async dispatch => {
  16. dispatch(actionPending(name))
  17. try{
  18. let payload = await promise
  19. dispatch(actionResolved(name, payload))
  20. return payload
  21. }
  22. catch(error){
  23. dispatch(actionRejected(name, error))
  24. }
  25. }
  26. const actionAuthLogin = token => ({type:'LOGIN', token})
  27. export const actionAuthLogout = () => ({type:"LOGOUT"})
  28. let log = async (login, password) => {
  29. let query = `query log($l: String!, $p: String!) {
  30. login(login: $l, password: $p)
  31. }`
  32. let variables = {
  33. "l": login,
  34. "p": password
  35. }
  36. let token = await shopGQL(query, variables)
  37. console.log(token)
  38. return token.data.login
  39. }
  40. const actionLogin = (login, password) => actionPromise("login", log(login, password))
  41. export const actionFullLogin = (login, password) => {
  42. return async (dispatch) => {
  43. let result = await dispatch(actionLogin(login, password))
  44. if(result) {
  45. dispatch(actionAuthLogin(result))
  46. dispatch(actionUserInfo())
  47. }
  48. }
  49. }
  50. const actionRegister = (login,password) =>
  51. actionPromise('reg',shopGQL(`mutation reg($login: String!, $password: String!){
  52. createUser(login:$login, password: $password){
  53. _id login
  54. }
  55. }`,{login,password}))
  56. export const actionFullRegister = (login,password) =>
  57. async dispatch => {
  58. let payload = await dispatch(actionRegister(login,password))
  59. if(payload.data.createUser != null){
  60. await dispatch(actionFullLogin(login,password))
  61. }
  62. else {
  63. console.log("exiciting user")
  64. }
  65. }
  66. export const actionTypeAd = (skip = 0) =>
  67. async(dispatch,getState) => {
  68. let ads = getState().promiseReducer.AdFind?.payload?.data.AdFind || []
  69. let res = await shopGQL(`
  70. query Ad($query:String){
  71. AdFind(query:$query){
  72. _id
  73. title
  74. description
  75. price
  76. images {
  77. url
  78. }
  79. comments {
  80. _id text owner {login} answerTo { owner { login}}
  81. }
  82. createdAt
  83. owner {login}
  84. }
  85. }
  86. `, {query: JSON.stringify([{},{sort: [{_id: -1}],skip : [ads.length], limit: [50]}])}
  87. )
  88. if(ads) {
  89. dispatch(actionResolved('AdFind',{data: {AdFind : [...ads, ...res?.data?.AdFind]}}))
  90. }
  91. }
  92. export const actionTypeAdOne = (id) =>
  93. actionPromise('AdFindOne',shopGQL(`
  94. query Ad($query:String){
  95. AdFindOne(query:$query){
  96. _id
  97. title
  98. description
  99. price
  100. images {
  101. url
  102. }
  103. comments {
  104. _id text owner {login} answerTo { text owner{ login}}
  105. }
  106. createdAt
  107. owner {login , createdAt}
  108. }
  109. }`,{query: JSON.stringify([{_id:id}])}))
  110. export const actionAddComment = (text) =>
  111. async(dispatch,getState) => {
  112. let adId = getState().promiseReducer.AdFindOne.payload.data.AdFindOne._id
  113. let addedCom = await dispatch(actionPromise('AddComment',shopGQL(`
  114. mutation Comment($comment: CommentInput){
  115. CommentUpsert(comment: $comment){
  116. _id
  117. text
  118. owner {login}
  119. ad {_id}
  120. }
  121. }`,{comment: {text,ad: {_id: adId}}})))
  122. if(addedCom) {
  123. dispatch(actionTypeAdOne(adId))
  124. }
  125. }
  126. export const actionPostAd = (title,description,price,files,_id) =>
  127. async dispatch => {
  128. let res = await dispatch(actionUploadFiles(files))
  129. let imagesId = res.map(({_id}) => ({_id}))
  130. if(res){
  131. let upsert = actionPromise('PostAd',shopGQL(`
  132. mutation Post($ad: AdInput){
  133. AdUpsert(ad: $ad) {
  134. _id
  135. title
  136. description
  137. price
  138. images {
  139. url
  140. }
  141. }
  142. }`,{ad: {title,description,price,images: imagesId,_id}}))
  143. if(upsert) {
  144. await dispatch(actionTypeAd())
  145. await dispatch(actionMyPosts())
  146. }
  147. }
  148. }
  149. export const actionMyPosts = () =>
  150. async (dispatch,getState) => {
  151. let userId = getState().authReducer.payload.sub.id
  152. return await dispatch(actionPromise('MyPosts',shopGQL(`
  153. query MyPosts($query: String){
  154. AdFind(query: $query){
  155. _id
  156. title
  157. description
  158. price
  159. images {
  160. url
  161. }
  162. comments {
  163. _id text owner {login} answerTo { owner { login}} ad {_id}
  164. }
  165. }
  166. }`,{query: JSON.stringify([{___owner: userId},{sort: [{_id: -1}]}])})))
  167. }
  168. export const actionUploadFile = (file) => {
  169. return actionPromise('photo',fetchFiles(file))
  170. };
  171. const fetchFiles = (file) => {
  172. let fd = new FormData
  173. fd.append('photo', file)
  174. return fetch('/upload', {
  175. method: "POST",
  176. headers: localStorage.authToken ? {Authorization: 'Bearer ' + localStorage.authToken} : {},
  177. body: fd
  178. }).then(res => res.json())
  179. }
  180. export const actionUploadFiles = (files) =>
  181. actionPromise('photos',Promise.all(files.map(file => fetchFiles(file))))
  182. const actionAvaAdd = (avaId) =>
  183. async (dispatch,getState) => {
  184. let userId = getState().authReducer.payload.sub.id
  185. await dispatch (actionPromise('ava',shopGQL(`mutation setAvatar($userId: String, $avaId: ID){
  186. UserUpsert(user:{_id: $userId, avatar: {_id: $avaId}}){
  187. _id, avatar{
  188. _id
  189. }
  190. }
  191. }`,{avaId,userId})))
  192. }
  193. export const actionAvaChange = (file) =>
  194. async (dispatch) => {
  195. let res = await dispatch(actionUploadFile(file))
  196. if(res) {
  197. await dispatch(actionAvaAdd(res._id))
  198. await dispatch(actionUserInfo())
  199. }
  200. }
  201. export const actionUserInfo = () =>
  202. async (dispatch,getState) => {
  203. let userId = getState().authReducer.payload.sub.id
  204. await dispatch(actionPromise('UserInfo',shopGQL(`
  205. query UserInfo($query:String){
  206. UserFindOne(query: $query){
  207. _id login avatar {url}
  208. }
  209. }`,{query: JSON.stringify([{_id: userId}])})))
  210. }
  211. const regexp = (string) => `/${string.split(" ").join('|').trim()}/`
  212. const toQuery = (queryString, fields = ["title", "description"]) => ({ $or: fields.map(string => ({ [string]: regexp(queryString) }))})
  213. export const actionSearch = (queryString) =>
  214. async (dispatch) =>
  215. await dispatch(actionPromise('SearchAd',shopGQL(`
  216. query AdFind($query: String){
  217. AdFind(query: $query) {
  218. _id
  219. title
  220. description
  221. price
  222. images {
  223. url
  224. }
  225. }
  226. }`,{query: JSON.stringify([toQuery(queryString),
  227. {
  228. sort: [{_id: -1}],
  229. limit: [15]
  230. }]
  231. )}
  232. )
  233. ))