diff --git a/api/src/controllers/communityController.js b/api/src/controllers/communityController.js index 4ccafa410..d81cf6371 100644 --- a/api/src/controllers/communityController.js +++ b/api/src/controllers/communityController.js @@ -40,11 +40,12 @@ const getCommunities = async (req, res) => { CASE WHEN "creatorId"=${req.user.id} THEN 'true' ELSE 'false' END - `), 'isCreator' + `), + 'isCreator' ], [ sequelize.literal(`( - SELECT COUNT("userId") + SELECT COUNT("userId") FROM communities_users WHERE "communityId" = communities.id AND active = true AND "userId" = ${req.user.id} )`), @@ -55,13 +56,15 @@ const getCommunities = async (req, res) => { } }) const totalPages = Math.ceil(communities.count / pageSize) - res.json({ - communities: communities.rows.map(rec => ({ ...rec.dataValues })), - totalItems: communities.count, - totalPages, - page, - pageSize - }).status(200) + res + .json({ + communities: communities.rows.map((rec) => ({ ...rec.dataValues })), + totalItems: communities.count, + totalPages, + page, + pageSize + }) + .status(200) } catch (error) { res.json(error) } @@ -72,11 +75,12 @@ const getCommunities = async (req, res) => { // @access Public const getUserCommunities = async (req, res) => { + console.log(req.body) const pageSize = 10 const page = Number(req.query.pageNumber) || 1 // const order = req.query.order || 'DESC' // const ordervalue = order && [['name', order]] - + console.log(req.user.id) db.Community.findAndCountAll({ offset: (page - 1) * pageSize, limit: pageSize, @@ -96,11 +100,12 @@ const getUserCommunities = async (req, res) => { CASE WHEN "creatorId"=${req.user.id} THEN 'true' ELSE 'false' END - `), 'isCreator' + `), + 'isCreator' ], [ sequelize.literal(`( - SELECT COUNT("userId") + SELECT COUNT("userId") FROM communities_users WHERE "communityId" = communities.id AND active = true AND "userId" = ${req.user.id} )`), @@ -111,23 +116,30 @@ const getUserCommunities = async (req, res) => { }, order: [['createdAt', 'DESC']], where: { deleted: false }, - include: [{ - model: db.User, - as: 'followers', - attributes: [], - where: { id: req.user.id }, - through: { attributes: [] } - }] + include: [ + { + model: db.User, + as: 'followers', + attributes: [], + where: { id: req.user.id }, + through: { attributes: [] } + } + ] }) - .then(communities => { + .then((communities) => { const totalPages = Math.ceil(communities.count / pageSize) - res.json({ - communities: communities.rows.map(rec => ({ ...rec.dataValues, attachment: changeFormat(rec.attachment) })), - totalItems: communities.count, - totalPages, - page, - pageSize - }).status(200) + res + .json({ + communities: communities.rows.map((rec) => ({ + ...rec.dataValues, + attachment: changeFormat(rec.attachment) + })), + totalItems: communities.count, + totalPages, + page, + pageSize + }) + .status(200) }) .catch((err) => res.json({ err }).status(400)) } @@ -147,8 +159,19 @@ const createCommunity = async (req, res) => { // auto follow through transactions if (req.body.auto_follow === 'true') { const result = await sequelize.transaction(async (t) => { - const community = await db.Community.create({ ...req.body, creatorId: req.user.id, slug: '', attachment: 'community/' + filename }, { transaction: t }) - const idArrays = await db.User.findAll({ attributes: ['id'] }, { transaction: t }) + const community = await db.Community.create( + { + ...req.body, + creatorId: req.user.id, + slug: '', + attachment: 'community/' + filename + }, + { transaction: t } + ) + const idArrays = await db.User.findAll( + { attributes: ['id'] }, + { transaction: t } + ) const allFollow = [] for (let i = 0; i < idArrays.length; i++) { @@ -166,11 +189,22 @@ const createCommunity = async (req, res) => { return res.json({ message: result }) } else { const followCommunity = await sequelize.transaction(async (t) => { - const community = await db.Community.create({ ...req.body, creatorId: req.user.id, slug: '', attachment: 'community/' + filename }, { transaction: t }) - await db.CommunityUser.create({ userId: req.user.id, communityId: community.id }, { transaction: t }) + const community = await db.Community.create( + { + ...req.body, + creatorId: req.user.id, + slug: '', + attachment: 'community/' + filename + }, + { transaction: t } + ) + await db.CommunityUser.create( + { userId: req.user.id, communityId: community.id }, + { transaction: t } + ) return true }) - if (followCommunity) return res.json({ message: 'Community is Created !!!' }).status(200) + if (followCommunity) { return res.json({ message: 'Community is Created !!!' }).status(200) } } } catch (error) { return res.json({ error: error.message }).status(400) @@ -184,9 +218,12 @@ const getCommunityById = async (req, res) => { const id = req.params.id db.Community.findByPk(id) - .then(communities => { + .then((communities) => { if (communities) { - res.json({ ...communities.dataValues, attachment: changeFormat(communities.dataValues.attachment) }) + res.json({ + ...communities.dataValues, + attachment: changeFormat(communities.dataValues.attachment) + }) } else { res.status(404) throw new Error('Community not found') @@ -214,14 +251,25 @@ const deleteCommunity = async (req, res) => { } const result = await sequelize.transaction(async (t) => { - const communityUserIds = await db.CommunityUser.findAll({ where: { communityId: id } }, { transaction: t }) + const communityUserIds = await db.CommunityUser.findAll( + { where: { communityId: id } }, + { transaction: t } + ) communityUserIds.forEach(async function (communityId) { const { id } = communityId - await db.CommunityUser.update({ active: false }, { where: { id } }, { transaction: t }) + await db.CommunityUser.update( + { active: false }, + { where: { id } }, + { transaction: t } + ) }) - await db.Community.update({ deleted: true }, { where: { id } }, { transaction: t }) + await db.Community.update( + { deleted: true }, + { where: { id } }, + { transaction: t } + ) return 'Community Deleted with links.' }) @@ -241,9 +289,7 @@ const deleteCommunity = async (req, res) => { // @access Private const updateCommunity = async (req, res) => { try { - const { - name, description, file, toggleActive - } = req.body + const { name, description, file, toggleActive } = req.body let filename = '' if (req.file) { @@ -274,11 +320,11 @@ const updateCommunity = async (req, res) => { // converting them to the array of ids not(object with ids) // to check console.log(followIdArrays) and newFollowIds - const newFollowIds = followIdArrays.map(item => item.userId) - const newUserIds = userIdArrays.map(item => item.id) + const newFollowIds = followIdArrays.map((item) => item.userId) + const newUserIds = userIdArrays.map((item) => item.id) // this is removing any duplicate items between newFollowIds and newUserIds - const idArrays = newUserIds.filter(item => { + const idArrays = newUserIds.filter((item) => { return newFollowIds.indexOf(item) === -1 }) @@ -295,33 +341,41 @@ const updateCommunity = async (req, res) => { await db.CommunityUser.bulkCreate(allFollow, { transaction: t }) if (!req.file) { - await db.Community.update({ ...req.body, slug: '' }, - { where: { id } }) + await db.Community.update( + { ...req.body, slug: '' }, + { where: { id } } + ) return 'Community is updated with autoFollow' } - await db.Community.update({ ...req.body, slug: '', attachment: 'community/' + filename }, - { where: { id } }) + await db.Community.update( + { ...req.body, slug: '', attachment: 'community/' + filename }, + { where: { id } } + ) return 'Community is updated with autoFollow' }) return res.json({ message: result }) } else { if (!req.file) { - await db.Community.update({ - name, - description - }, - { where: { id }, returning: true, attributes: ['id'] }) + await db.Community.update( + { + name, + description + }, + { where: { id }, returning: true, attributes: ['id'] } + ) return res.json({ message: 'Community Updated !!!' }).status(200) } - await db.Community.update({ - name, - description, - attachment: 'community/' + filename - }, - { where: { id }, returning: true, attributes: ['id'] }) + await db.Community.update( + { + name, + description, + attachment: 'community/' + filename + }, + { where: { id }, returning: true, attributes: ['id'] } + ) return res.json({ message: 'Community Updated !!!' }).status(200) } } else { @@ -340,11 +394,21 @@ const searchCommunityName = (req, res) => { const { name } = req.query const order = req.query.order || 'ASC' - db.Community.findAll({ where: { name: { [Op.iLike]: '%' + name + '%' } }, order: [['name', order]] }) - .then(communities => res.json({ - communities: communities.map(rec => ({ ...rec.dataValues, attachment: changeFormat(rec.attachment) })) - }).status(200)) - .catch(err => res.json({ error: err }).status(400)) + db.Community.findAll({ + where: { name: { [Op.iLike]: '%' + name + '%' } }, + order: [['name', order]] + }) + .then((communities) => + res + .json({ + communities: communities.map((rec) => ({ + ...rec.dataValues, + attachment: changeFormat(rec.attachment) + })) + }) + .status(200) + ) + .catch((err) => res.json({ error: err }).status(400)) } // @desc Search usercommunity name @@ -355,26 +419,44 @@ const searchUserCommunityName = (req, res) => { const order = req.query.order || 'ASC' db.Community.findAll({ - include: [{ - model: db.User, - as: 'creator' && 'followers', - attributes: ['id'], - where: { id: req.user.id }, - through: { - attributes: ['active'], - as: 'followStatus', - where: { - active: true + include: [ + { + model: db.User, + as: 'creator' && 'followers', + attributes: ['id'], + where: { id: req.user.id }, + through: { + attributes: ['active'], + as: 'followStatus', + where: { + active: true + } } } - }], + ], where: { name: { [Op.iLike]: '%' + name + '%' } }, order: [['name', order]] }) - .then(communities => res.json({ - communities: communities.map(rec => ({ ...rec.dataValues, attachment: changeFormat(rec.attachment) })) - }).status(200)) - .catch(err => res.json({ error: err }).status(400)) + .then((communities) => + res + .json({ + communities: communities.map((rec) => ({ + ...rec.dataValues, + attachment: changeFormat(rec.attachment) + })) + }) + .status(200) + ) + .catch((err) => res.json({ error: err }).status(400)) } -module.exports = { getCommunities, getUserCommunities, searchUserCommunityName, createCommunity, getCommunityById, deleteCommunity, updateCommunity, searchCommunityName } +module.exports = { + getCommunities, + getUserCommunities, + searchUserCommunityName, + createCommunity, + getCommunityById, + deleteCommunity, + updateCommunity, + searchCommunityName +} diff --git a/api/src/middleware/authMiddleware.js b/api/src/middleware/authMiddleware.js index 461eb9aab..dc7fcb62b 100644 --- a/api/src/middleware/authMiddleware.js +++ b/api/src/middleware/authMiddleware.js @@ -25,22 +25,28 @@ module.exports = async (req, res, next) => { } else { const jwk = require('./jwks.json') const pem = jwkToPem(jwk.keys[0]) - jwt.verify(token, pem, { algorithms: ['RS256'] }, function (err, decodedToken) { - if (err) { - if (err.message === 'jwt expired') { - throw Error('TokenExpired') - } else { - throw Error('InvalidToken') + jwt.verify( + token, + pem, + { algorithms: ['RS256'] }, + function (err, decodedToken) { + if (err) { + if (err.message === 'jwt expired') { + throw Error('TokenExpired') + } else { + throw Error('InvalidToken') + } } + recoded = decodedToken } - recoded = decodedToken - }) + ) } /* - * TODO: Maintain session and check again local session - */ + * TODO: Maintain session and check again local session + */ if (process.env.AUTH_METHOD !== 'cognito') { req.user = await db.User.findOne({ where: { userID: decoded.id } }) + console.log('user', req.user) } else if (recoded) { req.user = await db.User.findOne({ where: { userID: recoded.sub } }) } else { diff --git a/src/actions/userAction.js b/src/actions/userAction.js index eb10da583..34d9a69a0 100644 --- a/src/actions/userAction.js +++ b/src/actions/userAction.js @@ -3,58 +3,14 @@ import Amplify, { Auth } from 'aws-amplify' import { getApi, postApi } from '../utils/apiFunc' import FormData from 'form-data' -import { - ACCESS_TOKEN_FAIL, - ACCESS_TOKEN_REQUEST, - ACCESS_TOKEN_SUCCESS, - USER_DETAILS_FAIL, - USER_DETAILS_REQUEST, - USER_DETAILS_SUCCESS, - USER_LOGIN_FAIL, - USER_LOGIN_REQUEST, - USER_LOGIN_SUCCESS, - USER_LOGOUT, - USER_CONFIRM_CODE_REQUEST, - USER_CONFIRM_CODE_SUCCESS, - USER_CONFIRM_CODE_FAIL, - USER_RESEND_CODE_REQUEST, - USER_RESEND_CODE_SUCCESS, - USER_RESEND_CODE_FAIL, - USER_ATTR_CONFIRM_CODE_REQUEST, - USER_ATTR_CONFIRM_CODE_SUCCESS, - USER_ATTR_CONFIRM_CODE_FAIL, - USER_ATTR_RESEND_CODE_REQUEST, - USER_ATTR_RESEND_CODE_SUCCESS, - USER_ATTR_RESEND_CODE_FAIL, - USER_FORGOT_PWD_CONFIRM_CODE_REQUEST, - USER_FORGOT_PWD_CODE_SUCCESS, - USER_FORGOT_PWD_CODE_FAIL, - USER_FORGOT_PWD_CODE_RESET, - USER_FORGOT_PWD_RESEND_CODE_REQUEST, - USER_PASSWORD_CHANGE_REQUEST, - USER_PASSWORD_CHANGE_SUCCESS, - USER_PASSWORD_CHANGE_FAIL, - USER_REGISTER_FAIL, - USER_REGISTER_REQUEST, - USER_REGISTER_SUCCESS, - USER_UPDATE_REQUEST, - USER_UPDATE_SUCCESS, - USER_UPDATE_FAIL, - USER_LIST_FAIL, - USER_LIST_SUCCESS, - USER_LIST_REQUEST, - USER_DETAILS_RESET, - USER_SEARCH_REQUEST, - USER_SEARCH_SUCCESS, - USER_SEARCH_FAIL -} from '../constants/userConstants' +import * as User from '../constants/userConstants' if (process.env.REACT_APP_AUTH_METHOD === 'cognito') { Amplify.configure({ Auth: { - // REQUIRED only for Federated Authentication - Amazon Cognito Identity Pool ID - // identityPoolId: 'XX-XXXX-X:XXXXXXXX-XXXX-1234-abcd-1234567890ab', - // REQUIRED - Amazon Cognito Region + // REQUIRED only for Federated Authentication - Amazon Cognito Identity Pool ID + // identityPoolId: 'XX-XXXX-X:XXXXXXXX-XXXX-1234-abcd-1234567890ab', + // REQUIRED - Amazon Cognito Region region: process.env.REACT_APP_COGNITO_REGION, // OPTIONAL - Amazon Cognito Federated Identity Pool Region // Required only if it's different from Amazon Cognito Region @@ -89,7 +45,13 @@ if (process.env.REACT_APP_AUTH_METHOD === 'cognito') { // OPTIONAL - Hosted UI configuration oauth: { domain: process.env.REACT_APP_COGNITO_DOMAIN_NAME, // domain_name - scope: ['phone', 'email', 'profile', 'openid', 'aws.cognito.signin.user.admin'], + scope: [ + 'phone', + 'email', + 'profile', + 'openid', + 'aws.cognito.signin.user.admin' + ], redirectSignIn: process.env.FRONTEND_URL, redirectSignOut: process.env.FRONTEND_URL, responseType: 'token' // or 'token', note that REFRESH token will only be generated when the responseType is code @@ -98,43 +60,60 @@ if (process.env.REACT_APP_AUTH_METHOD === 'cognito') { }) } -export const register = (name, password) => async (dispatch) => { - try { - dispatch({ type: USER_REGISTER_REQUEST }) - dispatch({ type: USER_LOGIN_REQUEST }) - let userdata - if (process.env.REACT_APP_AUTH_METHOD !== 'cognito') { - const { data } = await postApi(dispatch, `${process.env.REACT_APP_API_BASE_URL}/api/users`, { name, password }) - userdata = data - } else { - await Auth.signUp({ - username: name, - password, - attributes: { - email: null +export const register = + ({ name, phone, email, password }) => + async (dispatch) => { + try { + dispatch({ type: User.USER_REGISTER_REQUEST }) + dispatch({ type: User.USER_LOGIN_REQUEST }) + let userdata + if (process.env.REACT_APP_AUTH_METHOD !== 'cognito') { + const { data } = await postApi( + dispatch, + `${process.env.REACT_APP_API_BASE_URL}/api/users`, + { name, phone, email, password } + ) + userdata = data + } else { + await Auth.signUp({ + username: name, + password, + attributes: { + email: email, + phone_number: phone + } + }) + const response = await Auth.signIn(name, password) + userdata = { + token: response?.signInUserSession?.idToken?.jwtToken, + id: response?.attributes?.sub || '' + } + + await postApi( + dispatch, + `${process.env.REACT_APP_API_BASE_URL}/api/users`, + { id: userdata.id } + ).catch((err) => console.log(err)) } - }) - const response = await Auth.signIn(name, password) - userdata = { token: response?.signInUserSession?.idToken?.jwtToken, id: response?.attributes?.sub || '' } - const { data } = await postApi(dispatch, `${process.env.REACT_APP_API_BASE_URL}/api/users`, { id: userdata.id }) - .catch(err => console.log(err)) + window.localStorage.setItem('userInfo', JSON.stringify(userdata)) + dispatch({ type: User.USER_REGISTER_SUCCESS, payload: userdata }) + dispatch({ type: User.USER_LOGIN_SUCCESS, payload: userdata }) + await routingCommunityNews(dispatch, false) + } catch (error) { + dispatch({ + type: User.USER_REGISTER_FAIL, + payload: + error.response && error.response.data.error + ? error.response.data.error + : error.message + }) + } } - window.localStorage.setItem('userInfo', JSON.stringify(userdata)) - dispatch({ type: USER_REGISTER_SUCCESS, payload: userdata }) - dispatch({ type: USER_LOGIN_SUCCESS, payload: userdata }) - await routingCommunityNews(dispatch, false) - } catch (error) { - dispatch({ - type: USER_REGISTER_FAIL, - payload: error.response && error.response.data.error ? error.response.data.error : error.message - }) - } -} export const login = (name, password) => async (dispatch) => { let data = {} try { - dispatch({ type: USER_LOGIN_REQUEST }) + dispatch({ type: User.USER_LOGIN_REQUEST }) if (process.env.REACT_APP_AUTH_METHOD !== 'cognito') { const { data: tokendata } = await postApi( dispatch, @@ -149,63 +128,80 @@ export const login = (name, password) => async (dispatch) => { id: response?.attributes?.sub || '' } window.localStorage.setItem('userInfo', JSON.stringify(data)) - await postApi(dispatch, `${process.env.REACT_APP_API_BASE_URL}/api/users`, { id: data.id }, { - headers: { - Authorization: 'Bearer ' + data.token + await postApi( + dispatch, + `${process.env.REACT_APP_API_BASE_URL}/api/users`, + { id: data.id }, + { + headers: { + Authorization: 'Bearer ' + data.token + } } - }) + ) - await axios.put(`${process.env.REACT_APP_API_BASE_URL}/api/users/profile`, { - firstName: response.attributes.given_name, - lastName: response.attributes.family_name, - birthday: response.attributes.birthdate, - phone: response.attributes.phone_number, - email: response.attributes.email - }, - { - headers: { - Authorization: 'Bearer ' + data.token + await axios.put( + `${process.env.REACT_APP_API_BASE_URL}/api/users/profile`, + { + firstName: response.attributes.given_name, + lastName: response.attributes.family_name, + birthday: response.attributes.birthdate, + phone: response.attributes.phone_number, + email: response.attributes.email + }, + { + headers: { + Authorization: 'Bearer ' + data.token + } } - }) + ) } window.localStorage.setItem('userInfo', JSON.stringify(data)) - dispatch({ type: USER_LOGIN_SUCCESS, payload: data }) + dispatch({ type: User.USER_LOGIN_SUCCESS, payload: data }) await routingCommunityNews(dispatch, true) } catch (error) { dispatch({ - type: USER_LOGIN_FAIL, - payload: error.response && error.response.data.error - ? error.response.data.error - : error.message + type: User.USER_LOGIN_FAIL, + payload: + error.response && error.response.data.error + ? error.response.data.error + : error.message }) } } export const getUserDetails = (id) => async (dispatch) => { try { - dispatch({ type: USER_DETAILS_REQUEST }) - const { data } = await getApi(dispatch, `${process.env.REACT_APP_API_BASE_URL}/api/users/profile/${id}`) - dispatch({ type: USER_DETAILS_SUCCESS, payload: data }) + dispatch({ type: User.USER_DETAILS_REQUEST }) + const { data } = await getApi( + dispatch, + `${process.env.REACT_APP_API_BASE_URL}/api/users/profile/${id}` + ) + dispatch({ type: User.USER_DETAILS_SUCCESS, payload: data }) } catch (error) { - const message = error.response && error.response.data.error ? error.response.data.error : error.message - dispatch({ type: USER_DETAILS_FAIL, payload: message }) + const message = + error.response && error.response.data.error + ? error.response.data.error + : error.message + dispatch({ type: User.USER_DETAILS_FAIL, payload: message }) } } export const checkAndUpdateToken = () => async (dispatch) => { - dispatch({ type: ACCESS_TOKEN_REQUEST }) - getApi(dispatch, `${process.env.REACT_APP_API_BASE_URL}/api/users/token`).then((data) => { - if (data) { - if (data?.response?.status === 201) { - dispatch({ type: ACCESS_TOKEN_SUCCESS, payload: true }) - return true + dispatch({ type: User.ACCESS_TOKEN_REQUEST }) + getApi(dispatch, `${process.env.REACT_APP_API_BASE_URL}/api/users/token`) + .then((data) => { + if (data) { + if (data?.response?.status === 201) { + dispatch({ type: User.ACCESS_TOKEN_SUCCESS, payload: true }) + return true + } + } else { + return tokenFailure(dispatch, 'Unauthorized') } - } else { + }) + .catch((data) => { return tokenFailure(dispatch, 'Unauthorized') - } - }).catch((data) => { - return tokenFailure(dispatch, 'Unauthorized') - /* const message = data.response && data.response.data.name ? data.response.data.name : data.message + /* const message = data.response && data.response.data.name ? data.response.data.name : data.message if (message === 'TokenExpired') { if (process.env.REACT_APP_AUTH_METHOD === 'cognito') { Auth.currentSession().then((res) => { @@ -214,8 +210,8 @@ export const checkAndUpdateToken = () => async (dispatch) => { if (userInfo.token == '') return tokenFailure(dispatch, message) else { window.localStorage.setItem('userInfo', JSON.stringify(userInfo)) - dispatch({ type: USER_LOGIN_SUCCESS, payload: userInfo }) - dispatch({ type: ACCESS_TOKEN_SUCCESS, payload: true }) + dispatch({ type: User.USER_LOGIN_SUCCESS, payload: userInfo }) + dispatch({ type: User.ACCESS_TOKEN_SUCCESS, payload: true }) return true } }).catch(data => tokenFailure(dispatch, 'Unauthorized')) @@ -226,8 +222,8 @@ export const checkAndUpdateToken = () => async (dispatch) => { if (userInfo.token == '') return tokenFailure(dispatch, message) else { window.localStorage.setItem('userInfo', JSON.stringify(userInfo)) - dispatch({ type: USER_LOGIN_SUCCESS, payload: userInfo }) - dispatch({ type: ACCESS_TOKEN_SUCCESS, payload: true }) + dispatch({ type: User.USER_LOGIN_SUCCESS, payload: userInfo }) + dispatch({ type: User.ACCESS_TOKEN_SUCCESS, payload: true }) return true } }).catch(data => tokenFailure(dispatch, 'Unauthorized')) @@ -235,21 +231,24 @@ export const checkAndUpdateToken = () => async (dispatch) => { } else { return tokenFailure(dispatch, 'Unauthorized') } */ - }) + }) } const tokenFailure = (dispatch, message) => { - dispatch({ type: USER_DETAILS_FAIL, payload: message }) + dispatch({ type: User.USER_DETAILS_FAIL, payload: message }) window.localStorage.clear() - dispatch({ type: USER_LOGOUT }) + dispatch({ type: User.USER_LOGOUT }) window.location.href = '/login' return false } export const getMyDetails = () => async (dispatch) => { try { - dispatch({ type: USER_DETAILS_REQUEST }) - const { data } = await getApi(dispatch, `${process.env.REACT_APP_API_BASE_URL}/api/users/profile`) + dispatch({ type: User.USER_DETAILS_REQUEST }) + const { data } = await getApi( + dispatch, + `${process.env.REACT_APP_API_BASE_URL}/api/users/profile` + ) const userdata = { firstName: data.firstName, lastName: data.lastName, @@ -262,21 +261,28 @@ export const getMyDetails = () => async (dispatch) => { role: data.role } if (process.env.REACT_APP_AUTH_METHOD === 'cognito') { - const { attributes } = await Auth.currentAuthenticatedUser({ bypassCache: true }) + const { attributes } = await Auth.currentAuthenticatedUser({ + bypassCache: true + }) userdata.phoneVerified = attributes.phone_number_verified userdata.emailVerified = attributes.email_verified } - dispatch({ type: USER_DETAILS_SUCCESS, payload: userdata }) + dispatch({ type: User.USER_DETAILS_SUCCESS, payload: userdata }) } catch (error) { - const message = error.response && error.response.data.error ? error.response.data.error : error.message - dispatch({ type: USER_DETAILS_FAIL, payload: message }) + const message = + error.response && error.response.data.error + ? error.response.data.error + : error.message + dispatch({ type: User.USER_DETAILS_FAIL, payload: message }) } } export const updateUser = (user, history) => async (dispatch, getState) => { try { - dispatch({ type: USER_UPDATE_REQUEST }) - const { userLogin: { userInfo } } = getState() + dispatch({ type: User.USER_UPDATE_REQUEST }) + const { + userLogin: { userInfo } + } = getState() const userProfileFormData = new FormData() userProfileFormData.append('firstName', user.firstName) userProfileFormData.append('lastName', user.lastName) @@ -296,7 +302,11 @@ export const updateUser = (user, history) => async (dispatch, getState) => { bypassCache: true }) } - const { data } = await axios.put(`${process.env.REACT_APP_API_BASE_URL}/api/users/profile`, userProfileFormData, config) + const { data } = await axios.put( + `${process.env.REACT_APP_API_BASE_URL}/api/users/profile`, + userProfileFormData, + config + ) if (process.env.REACT_APP_AUTH_METHOD === 'cognito') { const toBeUpdated = { email: user.email, @@ -307,210 +317,254 @@ export const updateUser = (user, history) => async (dispatch, getState) => { if (user.birthday) toBeUpdated.birthdate = user.birthday await Auth.updateUserAttributes(currentUser, toBeUpdated) } - dispatch({ type: USER_DETAILS_SUCCESS, payload: { user: data } }) + dispatch({ type: User.USER_DETAILS_SUCCESS, payload: { user: data } }) history.push('/myProfile') } catch (error) { - const message = error.response && error.response.data.error ? error.response.data.error : error.message + const message = + error.response && error.response.data.error + ? error.response.data.error + : error.message if (message === 'Not authorized, token failed') { dispatch(logout()) } - dispatch({ type: USER_UPDATE_FAIL, payload: message }) + dispatch({ type: User.USER_UPDATE_FAIL, payload: message }) } } export const listUsers = () => async (dispatch) => { try { - dispatch({ type: USER_LIST_REQUEST }) - const { data } = await getApi(dispatch, `${process.env.REACT_APP_API_BASE_URL}/api/users`) - dispatch({ type: USER_LIST_SUCCESS, payload: data }) + dispatch({ type: User.USER_LIST_REQUEST }) + const { data } = await getApi( + dispatch, + `${process.env.REACT_APP_API_BASE_URL}/api/users` + ) + dispatch({ type: User.USER_LIST_SUCCESS, payload: data }) } catch (error) { - const message = error.response && error.response.data.error ? error.response.data.error : error.message + const message = + error.response && error.response.data.error + ? error.response.data.error + : error.message if (message === 'Not authorized, token failed') { dispatch(logout()) } - dispatch({ type: USER_LIST_FAIL, payload: message }) + dispatch({ type: User.USER_LIST_FAIL, payload: message }) } } export const searchUsers = (search) => async (dispatch) => { try { - dispatch({ type: USER_SEARCH_REQUEST }) - const { data } = await getApi(dispatch, `${process.env.REACT_APP_API_BASE_URL}/api/users/search?name=${search}`) - dispatch({ type: USER_SEARCH_SUCCESS, payload: data }) + dispatch({ type: User.USER_SEARCH_REQUEST }) + const { data } = await getApi( + dispatch, + `${process.env.REACT_APP_API_BASE_URL}/api/users/search?name=${search}` + ) + dispatch({ type: User.USER_SEARCH_SUCCESS, payload: data }) } catch (error) { dispatch({ - type: USER_SEARCH_FAIL, - payload: error.response && error.response.data.error - ? error.response.data.error - : error.message + type: User.USER_SEARCH_FAIL, + payload: + error.response && error.response.data.error + ? error.response.data.error + : error.message }) } } export const logout = () => (dispatch) => { - Auth.signOut().then(() => { - window.localStorage.clear() - dispatch({ type: USER_LOGOUT }) - document.location.href = '/login' - }).catch(err => console.log(err)) + Auth.signOut() + .then(() => { + window.localStorage.clear() + dispatch({ type: User.USER_LOGOUT }) + document.location.href = '/login' + }) + .catch((err) => console.log(err)) } export const confirmPin = (username, code) => async (dispatch) => { try { - dispatch({ type: USER_CONFIRM_CODE_REQUEST }) + dispatch({ type: User.USER_CONFIRM_CODE_REQUEST }) if (process.env.REACT_APP_AUTH_METHOD === 'cognito') { const { data } = await Auth.confirmSignUp(username, code) - dispatch({ type: USER_CONFIRM_CODE_SUCCESS, payload: data }) + dispatch({ type: User.USER_CONFIRM_CODE_SUCCESS, payload: data }) } else { document.location.href = '/' } } catch (error) { dispatch({ - type: USER_CONFIRM_CODE_FAIL, - payload: error.response && error.response.data.error - ? error.response.data.error - : error.message + type: User.USER_CONFIRM_CODE_FAIL, + payload: + error.response && error.response.data.error + ? error.response.data.error + : error.message }) } } export const resendCodeAction = (username) => async (dispatch) => { try { - dispatch({ type: USER_RESEND_CODE_REQUEST }) + dispatch({ type: User.USER_RESEND_CODE_REQUEST }) if (process.env.REACT_APP_AUTH_METHOD === 'cognito') { const data = await Auth.resendSignUp(username) - dispatch({ type: USER_RESEND_CODE_SUCCESS }) + dispatch({ type: User.USER_RESEND_CODE_SUCCESS }) } else { document.location.href = '/' } } catch (error) { dispatch({ - type: USER_RESEND_CODE_FAIL, - payload: error.response && error.response.data.error - ? error.response.data.error - : error.message + type: User.USER_RESEND_CODE_FAIL, + payload: + error.response && error.response.data.error + ? error.response.data.error + : error.message }) } } export const verifyCurrentUserAttribute = (attr) => async (dispatch) => { try { - dispatch({ type: USER_ATTR_RESEND_CODE_REQUEST }) - dispatch({ type: USER_ATTR_CONFIRM_CODE_REQUEST }) + dispatch({ type: User.USER_ATTR_RESEND_CODE_REQUEST }) + dispatch({ type: User.USER_ATTR_CONFIRM_CODE_REQUEST }) if (process.env.REACT_APP_AUTH_METHOD === 'cognito') { const data = await Auth.verifyCurrentUserAttribute(attr) - dispatch({ type: USER_ATTR_RESEND_CODE_SUCCESS }) + dispatch({ type: User.USER_ATTR_RESEND_CODE_SUCCESS }) } else { document.location.href = '/' } } catch (error) { dispatch({ - type: USER_ATTR_RESEND_CODE_FAIL, - payload: error.response && error.response.data.error - ? error.response.data.error - : error.message + type: User.USER_ATTR_RESEND_CODE_FAIL, + payload: + error.response && error.response.data.error + ? error.response.data.error + : error.message }) } } -export const verifyCurrentUserAttributeSubmit = (attr, code) => async (dispatch, getState) => { - try { - dispatch({ type: USER_ATTR_CONFIRM_CODE_REQUEST }) - dispatch({ type: USER_ATTR_RESEND_CODE_REQUEST }) - const { userDetails: { user } } = getState() - if (process.env.REACT_APP_AUTH_METHOD === 'cognito') { - await Auth.verifyCurrentUserAttributeSubmit(attr, code) - const userdata = user - const { attributes } = await Auth.currentAuthenticatedUser({ - bypassCache: true +export const verifyCurrentUserAttributeSubmit = + (attr, code) => async (dispatch, getState) => { + try { + dispatch({ type: User.USER_ATTR_CONFIRM_CODE_REQUEST }) + dispatch({ type: User.USER_ATTR_RESEND_CODE_REQUEST }) + const { + userDetails: { user } + } = getState() + if (process.env.REACT_APP_AUTH_METHOD === 'cognito') { + await Auth.verifyCurrentUserAttributeSubmit(attr, code) + const userdata = user + const { attributes } = await Auth.currentAuthenticatedUser({ + bypassCache: true + }) + userdata.phoneVerified = attributes.phone_number_verified + userdata.emailVerified = attributes.email_verified + dispatch({ type: User.USER_DETAILS_SUCCESS, payload: userdata }) + dispatch({ type: User.USER_ATTR_CONFIRM_CODE_SUCCESS }) + } else { + document.location.href = '/myProfile' + } + } catch (error) { + dispatch({ + type: User.USER_ATTR_CONFIRM_CODE_FAIL, + payload: + error.response && error.response.data.error + ? error.response.data.error + : error.message }) - userdata.phoneVerified = attributes.phone_number_verified - userdata.emailVerified = attributes.email_verified - dispatch({ type: USER_DETAILS_SUCCESS, payload: userdata }) - dispatch({ type: USER_ATTR_CONFIRM_CODE_SUCCESS }) - } else { - document.location.href = '/myProfile' } - } catch (error) { - dispatch({ - type: USER_ATTR_CONFIRM_CODE_FAIL, - payload: error.response && error.response.data.error - ? error.response.data.error - : error.message - }) } -} export const forgotPassword = (username) => async (dispatch) => { try { - dispatch({ type: USER_FORGOT_PWD_RESEND_CODE_REQUEST }) + dispatch({ type: User.USER_FORGOT_PWD_RESEND_CODE_REQUEST }) if (process.env.REACT_APP_AUTH_METHOD === 'cognito') { const data = await Auth.forgotPassword(username) - dispatch({ type: USER_FORGOT_PWD_CODE_SUCCESS, payload: `Code has been sent to your ${data.CodeDeliveryDetails.AttributeName.split('_').join(' ')}.` }) + dispatch({ + type: User.USER_FORGOT_PWD_CODE_SUCCESS, + payload: `Code has been sent to your ${data.CodeDeliveryDetails.AttributeName.split( + '_' + ).join(' ')}.` + }) return data } else { document.location.href = '/' } } catch (error) { dispatch({ - type: USER_FORGOT_PWD_CODE_FAIL, - payload: error.response && error.response.data.error - ? error.response.data.error - : error.message + type: User.USER_FORGOT_PWD_CODE_FAIL, + payload: + error.response && error.response.data.error + ? error.response.data.error + : error.message }) } } -export const forgotPasswordSubmit = (username, code, confirmPassword, history) => async (dispatch) => { - try { - dispatch({ type: USER_FORGOT_PWD_CONFIRM_CODE_REQUEST }) - if (process.env.REACT_APP_AUTH_METHOD === 'cognito') { - await Auth.forgotPasswordSubmit(username, code, confirmPassword) - dispatch({ type: USER_FORGOT_PWD_CODE_SUCCESS, payload: 'Password has been changed successfully.' }) - dispatch({ type: USER_FORGOT_PWD_CODE_RESET }) - history.push('/login') - } else { - document.location.href = '/' +export const forgotPasswordSubmit = + (username, code, confirmPassword, history) => async (dispatch) => { + try { + dispatch({ type: User.USER_FORGOT_PWD_CONFIRM_CODE_REQUEST }) + if (process.env.REACT_APP_AUTH_METHOD === 'cognito') { + await Auth.forgotPasswordSubmit(username, code, confirmPassword) + dispatch({ + type: User.USER_FORGOT_PWD_CODE_SUCCESS, + payload: 'Password has been changed successfully.' + }) + dispatch({ type: User.USER_FORGOT_PWD_CODE_RESET }) + history.push('/login') + } else { + document.location.href = '/' + } + } catch (error) { + dispatch({ + type: User.USER_FORGOT_PWD_CODE_FAIL, + payload: + error?.response && error.response.data.error + ? error.response.data.error + : error.message + }) } - } catch (error) { - dispatch({ - type: USER_FORGOT_PWD_CODE_FAIL, - payload: error?.response && error.response.data.error - ? error.response.data.error - : error.message - }) } -} -export const changePassword = (oldPassword, newPassword) => async (dispatch) => { - let resdata - try { - dispatch({ type: USER_PASSWORD_CHANGE_REQUEST }) - if (process.env.REACT_APP_AUTH_METHOD !== 'cognito') { - const { data } = await postApi(dispatch, - `${process.env.REACT_APP_API_BASE_URL}/api/users/changePassword`, - { oldPassword, newPassword } - ) - resdata = data - } else { - const user = await Auth.currentAuthenticatedUser() - resdata = await Auth.changePassword(user, oldPassword, newPassword) - } +export const changePassword = + (oldPassword, newPassword) => async (dispatch) => { + let resdata + try { + dispatch({ type: User.USER_PASSWORD_CHANGE_REQUEST }) + if (process.env.REACT_APP_AUTH_METHOD !== 'cognito') { + const { data } = await postApi( + dispatch, + `${process.env.REACT_APP_API_BASE_URL}/api/users/changePassword`, + { oldPassword, newPassword } + ) + resdata = data + } else { + const user = await Auth.currentAuthenticatedUser() + resdata = await Auth.changePassword(user, oldPassword, newPassword) + } - dispatch({ type: USER_PASSWORD_CHANGE_SUCCESS }) - } catch (error) { - dispatch({ - type: USER_PASSWORD_CHANGE_FAIL, - payload: error.response && error.response.data.message - ? (error.response.data.__type === 'NotAuthorizedException' ? 'Incorrect old password.' : error.response.data.message) - : error.message - }) + dispatch({ type: User.USER_PASSWORD_CHANGE_SUCCESS }) + } catch (error) { + dispatch({ + type: User.USER_PASSWORD_CHANGE_FAIL, + payload: + error.response && error.response.data.message + ? error.response.data.__type === 'NotAuthorizedException' + ? 'Incorrect old password.' + : error.response.data.message + : error.message + }) + } } -} export const routingCommunityNews = async (dispatch, route = false) => { - const communityData = await getApi(dispatch, `${process.env.REACT_APP_API_BASE_URL}/api/communities/user`) - window.localStorage.setItem('currentCommunity', JSON.stringify(communityData.data.communities[0])) + const communityData = await getApi( + dispatch, + `${process.env.REACT_APP_API_BASE_URL}/api/communities/user` + ) + window.localStorage.setItem( + 'currentCommunity', + JSON.stringify(communityData.data.communities[0]) + ) if (route) { document.location.href = `/community-page-news/${communityData.data.communities[0].slug}` } diff --git a/src/assets/images/email.svg b/src/assets/images/email.svg new file mode 100644 index 000000000..b228cb1bf --- /dev/null +++ b/src/assets/images/email.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/images/phone-call-outline.svg b/src/assets/images/phone-call-outline.svg new file mode 100644 index 000000000..881ce1e10 --- /dev/null +++ b/src/assets/images/phone-call-outline.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/components/input/Input.jsx b/src/components/input/Input.jsx index 38ae8b15c..d45ba0bfa 100644 --- a/src/components/input/Input.jsx +++ b/src/components/input/Input.jsx @@ -17,7 +17,7 @@ const Input = React.forwardRef( children, noIcon, disabled, - onChange + onChange = () => {} }, ref ) => { @@ -55,7 +55,10 @@ const Input = React.forwardRef( id={id} ref={ref} type={type} - onChange={(e) => setShowLabel(e.target.value)} + onChange={(e) => { + setShowLabel(e.target.value) + onChange(e) + }} disabled={disabled} autoComplete='off' /> diff --git a/src/components/input/Input.scss b/src/components/input/Input.scss index 7029b6534..11ed4f17d 100644 --- a/src/components/input/Input.scss +++ b/src/components/input/Input.scss @@ -51,14 +51,25 @@ width: 100%; .icon { - align-items: center; display: flex; - flex-direction: column; + align-items: center; + justify-content: flex-start; + flex-direction: row-reverse; height: 24px; padding: 3px 0; - width: 24px; margin-right: 0.5em; + span { + font-family: inherit; + font-size: 1.05em; + background-color: transparent; + color: var(--primary-grey); + } + + path { + fill: var(--primary-color); + } + img { width: 100%; height: 100%; @@ -107,21 +118,21 @@ text-transform: inherit; } - input[type="number"] { + input[type='number'] { -moz-appearance: textfield; } - input[type="number"]::-webkit-outer-spin-button, - input[type="number"]::-webkit-inner-spin-button { + input[type='number']::-webkit-outer-spin-button, + input[type='number']::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; } - input[type="date"] { + input[type='date'] { color: var(--primary-grey); } - input[type="date"]::-webkit-calendar-picker-indicator { + input[type='date']::-webkit-calendar-picker-indicator { display: none; } diff --git a/src/components/signInSignUp/Icon.jsx b/src/components/signInSignUp/Icon.jsx new file mode 100644 index 000000000..dd402637d --- /dev/null +++ b/src/components/signInSignUp/Icon.jsx @@ -0,0 +1,19 @@ +import PhoneNumber from './PhoneNumber' +import { ReactComponent as UserAvatar } from '../../assets/images/user-green-outline.svg' +import { ReactComponent as Email } from '../../assets/images/email.svg' + +const Icon = ({ checkType, inputVal, setInputVal }) => { + return ( + <> + {checkType === 'email' ? ( + + ) : checkType === 'number' ? ( + + ) : ( + + )} + + ) +} + +export default Icon diff --git a/src/components/signInSignUp/PhoneNumber.jsx b/src/components/signInSignUp/PhoneNumber.jsx new file mode 100644 index 000000000..bbf1573cf --- /dev/null +++ b/src/components/signInSignUp/PhoneNumber.jsx @@ -0,0 +1,14 @@ +import PhoneInput from 'react-phone-number-input' + +const PhoneNumber = ({ value, setValue }) => { + return ( + + ) +} +export default PhoneNumber diff --git a/src/components/signInSignUp/Sign.jsx b/src/components/signInSignUp/Sign.jsx new file mode 100644 index 000000000..316bab08e --- /dev/null +++ b/src/components/signInSignUp/Sign.jsx @@ -0,0 +1,120 @@ +import { useState } from 'react' +import { Link } from 'react-router-dom' +import { useForm } from 'react-hook-form' +import useCheckInputType from './useCheckInputType' +import Icon from './Icon' +import OAuthBtn from '../oAuthBtn/OAuthBtn' +import Checkbox from '../checkbox/Checkbox' +import Button from '../button/Button' +import Input from '../input/Input' +import { ReactComponent as Lock } from '../../assets/images/lock-outline.svg' + +const Sign = ({ + onSubmit, + title, + inputVal, + setInputVal, + spanText, + google, + facebook, + haveAc, + noAc, + signIn, + error, + text, + isSignUp, + welcomeBack +}) => { + const { register: regi, handleSubmit, errors } = useForm() + const [showPassword, setShowPassword] = useState(false) + const togglePasswordVisibility = () => { + setShowPassword(!showPassword) + } + const { checkType, inputPlaceholder } = useCheckInputType(inputVal) + + return ( +
+

{title}

+
+ {error &&
{error}
} + setInputVal(e.target.value)} + > + + + + + +
+ {isSignUp ? ( + + ) : ( + + )} +
+ +
+
+
+ +
+
+

{haveAc || noAc}

+ + {welcomeBack || signIn} + +
+
+
+ ) +} + +export default Sign diff --git a/src/components/signInSignUp/SignIn.jsx b/src/components/signInSignUp/SignIn.jsx index 044b9826f..32be55f57 100644 --- a/src/components/signInSignUp/SignIn.jsx +++ b/src/components/signInSignUp/SignIn.jsx @@ -1,188 +1,52 @@ import React, { useState, useEffect } from 'react' -import { Link, useHistory } from 'react-router-dom' +import { useHistory } from 'react-router-dom' import { useDispatch, useSelector } from 'react-redux' -import { useForm } from 'react-hook-form' import { login } from '../../actions/userAction' -import { USER_LOGIN_SUCCESS } from '../../constants/userConstants' import { SignInSignUpData } from './SignInSignUpData' - -import Button from '../button/Button' -import Checkbox from '../checkbox/Checkbox' -import Input from '../input/Input' -import OAuthBtn from '../oAuthBtn/OAuthBtn' -import { ReactComponent as UserAvatar } from '../../assets/images/user-green-outline.svg' -import { ReactComponent as Lock } from '../../assets/images/lock-outline.svg' import './SignInSignUp.scss' -import { listUserCommunities, visitCommunity } from '../../actions/communityActions' +import { visitCommunity } from '../../actions/communityActions' +import Sign from './Sign' const SignIn = () => { - const { welcomeBack, rememberMe, text1, google, facebook, failMessage } = + const { welcomeBack, text1, google, facebook, noAc, signIn } = SignInSignUpData - const [user, setUser] = useState(null) const history = useHistory() const dispatch = useDispatch() const userLogin = useSelector((state) => state.userLogin) const { currentCommunity } = useSelector((state) => state.activeCommunity) const { loading, error, userInfo } = userLogin - const { register: regi, errors, handleSubmit } = useForm() - - const [terms, setTerms] = useState(false) - const [termsError, setTermsError] = useState(false) - const [showPassword, setShowPassword] = useState(false) - - const togglePasswordVisibility = () => { - setShowPassword(!showPassword) - } + const [inputVal, setInputVal] = useState('') useEffect(() => { - /* Hub.listen("auth", ({ payload: { event, data } }) => { - console.log(event); - switch (event) { - case "signIn": - case "cognitoHostedUI": - getUser().then((userData) => setUser(userData)); - break; - case "signOut": - setUser(null); - break; - case "signIn_failure": - case "cognitoHostedUI_failure": - console.log("Sign in failure", data); - break; - default: - console.log("Sign in failure"); - } - }); */ - if (userInfo) { if (currentCommunity) { return dispatch(visitCommunity(currentCommunity.id)) } } - - // getUser().then((userData) => setUser(userData)); }, [history, userInfo, dispatch]) - function getUser () { - /* return Auth.currentAuthenticatedUser() - .then((userData) => userData) - .catch(() => console.log("Not signed in")); */ - } - - // async function signIn(username, password) { - // try { - // const user = await Auth.signIn(username, password); - // if (user) { - // localStorage.setItem("userInfo", JSON.stringify(user)); - // dispatch({ - // type: USER_LOGIN_SUCCESS, - // payload: user, - // }); - // history.push("/community-page-news"); - // } - // } catch (error) { - // const code = error.code; - // switch (code) { - // case "NotAuthorizedException": - // setUserError("NotAuthorizedException"); - // setPasswordError("NotAuthorizedException"); - // return; - // default: - // return false; - // } - // } - // } - - const loginWithFacebook = (e) => { - e.preventDefault() - // Auth.federatedSignIn({ provider: "Facebook" }); - } - - const loginWithGoogle = (e) => { - e.preventDefault() - // Auth.federatedSignIn({ provider: "Google" }); - } - - const onSubmit = ({ username, password }) => { - dispatch(login(username, password)) + const onSubmit = ({ user, password }) => { + dispatch(login(user, password)) } return ( -
-

Sign In

-
- {error &&
{error}
} - - - - - - - - - -
- -
- -
-
- -
- -
- -
-

- Don't have an account yet? -

- - Become a member! - -
-
-
+ ) } diff --git a/src/components/signInSignUp/SignInSignUp.scss b/src/components/signInSignUp/SignInSignUp.scss index 49e319fdf..5ac231943 100644 --- a/src/components/signInSignUp/SignInSignUp.scss +++ b/src/components/signInSignUp/SignInSignUp.scss @@ -5,7 +5,7 @@ height: inherit; //@media only screen and (max-width: 1440px) { - width: 100%; + width: 100%; //} /*@media only screen and (max-width: 375px) { @@ -22,7 +22,7 @@ min-height: 40px; white-space: nowrap; color: var(--primary-white); - font-family: "IBM Plex Sans-SemiBold", Helvetica, sans-serif; + font-family: 'IBM Plex Sans-SemiBold', Helvetica, sans-serif; font-size: 35px; font-style: normal; font-weight: 600; @@ -129,7 +129,7 @@ @media only screen and (min-width: 1024px) { flex-direction: row; } - + @media only screen and (max-width: 1023px) and (min-width: 767px) { flex-direction: column; align-items: flex-start; @@ -226,7 +226,7 @@ @media only screen and (min-width: 1024px) { flex-direction: row; } - + @media only screen and (max-width: 1023px) and (min-width: 767px) { flex-direction: column; } @@ -243,7 +243,7 @@ } .span { - font-family: "IBM Plex Sans-Regular", Helvetica, sans-serif; + font-family: 'IBM Plex Sans-Regular', Helvetica, sans-serif; font-size: 16px; &-1 { @@ -262,7 +262,7 @@ .white16px { color: var(--primary-white); - font-family: "IBM Plex Sans-SemiBold", Helvetica, sans-serif; + font-family: 'IBM Plex Sans-SemiBold', Helvetica, sans-serif; font-size: 16px; font-style: normal; font-weight: 600; @@ -270,7 +270,7 @@ .green16px { color: var(--primary-color); - font-family: "IBM Plex Sans-SemiBold", Helvetica, sans-serif; + font-family: 'IBM Plex Sans-SemiBold', Helvetica, sans-serif; font-size: 16px; font-style: normal; font-weight: 600; @@ -278,7 +278,7 @@ .transparent16px { color: transparent; - font-family: "IBM Plex Sans-Regular", Helvetica, sans-serif; + font-family: 'IBM Plex Sans-Regular', Helvetica, sans-serif; font-size: 16px; font-style: normal; font-weight: 400; @@ -294,3 +294,53 @@ margin-top: 1em; } } +.signInput { + display: flex; + align-items: center; + + .PhoneInputInput { + display: none; + } + .PhoneInputCountry { + position: relative; + align-self: stretch; + display: flex; + align-items: center; + margin-right: 0.35em; + } + .PhoneInputCountrySelect { + position: absolute; + top: 0; + left: 0; + height: 100%; + width: 100%; + z-index: 1; + border: 0; + opacity: 0; + cursor: pointer; + } + .PhoneInputCountryIcon { + width: calc(1em * 1.5); + height: 1em; + } + .PhoneInputCountry { + select { + background: var(--background-color); + border: none; + outline: none; + padding: 0.5em; + option { + font-family: var(--font-family); + font-size: 1.28em; + margin: 1.5em 0; + color: #ffff; + padding: 1em; + cursor: pointer; + + &:hover { + background-color: var(--primary-color) !important; + } + } + } + } +} diff --git a/src/components/signInSignUp/SignInSignUpData.js b/src/components/signInSignUp/SignInSignUpData.js index 563aa8c5c..8b18d3a9f 100644 --- a/src/components/signInSignUp/SignInSignUpData.js +++ b/src/components/signInSignUp/SignInSignUpData.js @@ -1,6 +1,5 @@ export const SignInSignUpData = { welcomeBack: 'Become a member', - rememberMe: 'Remember Me', signIn: 'Sign in', forgotPassword: 'Forgot Password?', text1: 'Sign In with services', @@ -12,5 +11,8 @@ export const SignInSignUpData = { facebook: 'Facebook', spanText4: 'Already have an account?', subtract2: '', - failMessage: ' Please enter correct username or password.' + failMessage: ' Please enter correct username or password.', + haveAc: 'Already have an Account?', + noAc: 'Don\'t have an account yet?', + signUp: 'Become a member!' } diff --git a/src/components/signInSignUp/SignUp.jsx b/src/components/signInSignUp/SignUp.jsx index c020abaa5..5dfb004cc 100644 --- a/src/components/signInSignUp/SignUp.jsx +++ b/src/components/signInSignUp/SignUp.jsx @@ -1,43 +1,24 @@ import React, { useState, useEffect } from 'react' -import { Link, useHistory } from 'react-router-dom' +import { useHistory } from 'react-router-dom' import { useDispatch, useSelector } from 'react-redux' -import { useForm } from 'react-hook-form' import { register } from '../../actions/userAction' -import { USER_LOGIN_SUCCESS } from '../../constants/userConstants' import { SignInSignUpData } from './SignInSignUpData' +import useCheckInputType from './useCheckInputType' +import Sign from './Sign' -import Button from '../button/Button' -import Checkbox from '../checkbox/Checkbox' -import OAuthBtn from '../oAuthBtn/OAuthBtn' -import Input from '../input/Input' -import { ReactComponent as UserAvatar } from '../../assets/images/user-green-outline.svg' -import { ReactComponent as Lock } from '../../assets/images/lock-outline.svg' import './SignInSignUp.scss' const SignIn = () => { - const { - welcomeBack, - spanText, - text2, - google, - facebook, - signIn, - failMessage - } = SignInSignUpData - + const { welcomeBack, spanText, text2, google, facebook, signIn, haveAc } = + SignInSignUpData const history = useHistory() - const { register: regi, handleSubmit, errors } = useForm() - const dispatch = useDispatch() - const [showPassword, setShowPassword] = useState(false) - - const togglePasswordVisibility = () => { - setShowPassword(!showPassword) - } + const [inputVal, setInputVal] = useState('') const userRegister = useSelector((state) => state.userRegister) const { loading, error, userInfo } = userRegister + const { checkType } = useCheckInputType(inputVal) useEffect(() => { if (userInfo) { @@ -45,79 +26,31 @@ const SignIn = () => { } }, [history, userInfo]) - const onSubmit = ({ username, password }) => { - return dispatch(register(username, password)) + const onSubmit = ({ user, password }) => { + const phone = checkType === 'number' ? user : null + const email = checkType === 'email' ? user : null + const name = + checkType === 'username' + ? user + : Math.random().toString(36).substring(3, 6) + new Date().getTime() + return dispatch(register({ name, phone, email, password })) } return ( -
-

{welcomeBack}

-
- {error &&
{error}
} - - - - - - -
-
- -
-
-
-
-
- -
-
-

Already have an Account?

- - {signIn} - -
-
-
+ ) } diff --git a/src/components/signInSignUp/useCheckInputType.js b/src/components/signInSignUp/useCheckInputType.js new file mode 100644 index 000000000..80264e297 --- /dev/null +++ b/src/components/signInSignUp/useCheckInputType.js @@ -0,0 +1,27 @@ +import { useState, useEffect } from 'react' + +const useCheckInputType = (inputVal) => { + const [checkType, setCheckType] = useState('') + + useEffect(() => { + const regexEmail = + /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ + const regexNumber = /^[+]*[(]{0,1}[0-9]{1,4}[)]{0,1}[-\s\./0-9]*$/ + regexEmail.test(inputVal) + ? setCheckType('email') + : regexNumber.test(inputVal) + ? setCheckType('number') + : setCheckType('username') + }, [inputVal]) + + const inputPlaceholder = + checkType === 'email' + ? 'Email' + : checkType === 'number' + ? 'Phone Number' + : 'Username' + + return { checkType, inputPlaceholder } +} + +export default useCheckInputType diff --git a/src/screens/congratulation/Congratulation.scss b/src/screens/congratulation/Congratulation.scss index 87d5e07d4..068ea0e05 100644 --- a/src/screens/congratulation/Congratulation.scss +++ b/src/screens/congratulation/Congratulation.scss @@ -228,73 +228,73 @@ .block-error { border-color: var(--secondary-red) !important; } -} -.PhoneInput { - display: flex; - align-items: center; - justify-content: flex-start; - width: 100%; - height: 80px; - border-radius: 4px; - border: 1px solid var(--dropdowns); - padding: 0 1em; - - &:focus-within { - border: 1px solid var(--primary-color); - } - - &-error { - border-color: var(--secondary-red) !important; - } - - .PhoneInputCountry { - position: relative; - align-self: stretch; + .PhoneInput { display: flex; align-items: center; - width: 15%; - - .PhoneInputCountrySelect { - position: absolute; - top: 0; - left: 0; - height: 100%; - width: 100%; - z-index: 1; - border: 0; - opacity: 0; - cursor: pointer; + justify-content: flex-start; + width: 100%; + height: 80px; + border-radius: 4px; + border: 1px solid var(--dropdowns); + padding: 0 1em; + + &:focus-within { + border: 1px solid var(--primary-color); } - .PhoneInputCountryIcon { - width: calc(100% * 1.5); - height: 100%; - .PhoneInputCountryIconImg { - display: block; - width: 80%; + &-error { + border-color: var(--secondary-red) !important; + } + + .PhoneInputCountry { + position: relative; + align-self: stretch; + display: flex; + align-items: center; + width: 15%; + + .PhoneInputCountrySelect { + position: absolute; + top: 0; + left: 0; height: 100%; - background-color: transparent !important; - color: var(--primary-color); + width: 100%; + z-index: 1; + border: 0; + opacity: 0; + cursor: pointer; + } + .PhoneInputCountryIcon { + width: calc(100% * 1.5); + height: 100%; + + .PhoneInputCountryIconImg { + display: block; + width: 80%; + height: 100%; + background-color: transparent !important; + color: var(--primary-color); + } + } + .PhoneInputCountrySelectArrow { + display: none; } } - .PhoneInputCountrySelectArrow { - display: none; - } - } - input { - padding: 1em 0.4em; - border-radius: 0.2em; - border: 1px solid #cfcfcf; - background-color: transparent !important; - color: var(--primary-grey); - outline: none; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - font-family: inherit; - width: 85%; - font-size: 1.05em; - border: none; + input { + padding: 1em 0.4em; + border-radius: 0.2em; + border: 1px solid #cfcfcf; + background-color: transparent !important; + color: var(--primary-grey); + outline: none; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + font-family: inherit; + width: 85%; + font-size: 1.05em; + border: none; + } } } diff --git a/src/utils/apiFunc.jsx b/src/utils/apiFunc.jsx index c01166ee4..1b6b1f812 100644 --- a/src/utils/apiFunc.jsx +++ b/src/utils/apiFunc.jsx @@ -2,7 +2,7 @@ import axios from 'axios' export const configFunc = (options = { headers: {} }) => { const userdata = window.localStorage.getItem('userInfo') - const token = JSON.parse(userdata).token + const token = JSON.parse(userdata)?.token const headers = { 'Content-Type': 'application/json' } headers.Authorization = token && `Bearer ${token}` return { headers: { ...headers, ...options.headers } }