/** @module swisstennis/state */ import { call, put, takeEvery } from 'redux-saga/effects' import { SZTM_API } from '../local-constants' import { normalizePhone } from '../helpers' import api from '../api' /** * state.js * * Collection of everything which has to do with state changes. **/ /** actionTypes define what actions are handeled by the reducer. */ export const actions = { changeForm: (data) => { return { type: 'SMS/CHANGE_FORM', data } }, setRecipients: (data) => { return { type: 'SMS/SET_RECIPIENTS', data } }, addRecipient: (data) => { return { type: 'SMS/ADD_RECIPIENT', data } }, sendSMSRequest: (data) => { return { type: 'SMS/SEND_REQUEST', data } }, sendSMSSuccess: (data) => { return { type: 'SMS/SEND_SUCCESS', data } }, sendSMSFailure: (error) => { return { type: 'SMS/SEND_FAILURE', error } }, getCreditRequest: (data) => { return { type: 'SMS/CREDIT_REQUEST', data } }, getCreditSuccess: (data) => { return { type: 'SMS/CREDIT_SUCCESS', data } }, getCreditFailure: (error) => { return { type: 'SMS/CREDIT_FAILURE', error } } } console.log('State actions', actions) /** state definition */ export const state = { recipients: [], sender: 'SZTM', body: '', sending: false, newRecipient: '', message: '', credit: '?' } console.log('State state', state) /** reducer is called by the redux dispatcher and handles all component actions */ export function reducer (state = [], action) { switch (action.type) { case 'SMS/CHANGE_FORM': return { ...state, ...action.data } case 'SMS/SET_RECIPIENTS': const recipients = action.data.map(player => player.phone).filter(number => !!number) console.log(recipients) return { ...state, recipients } case 'SMS/ADD_RECIPIENT': const number = normalizePhone(action.data) if (number) { return { ...state, recipients: [ number, ...state.recipients ], newRecipient: '' } } else { return state } case 'SMS/SEND_REQUEST': return { ...state, sending: true } case 'SMS/SEND_SUCCESS': return { ...state, sending: false, recipients: [], newRecipient: '', body: '' } case 'SMS/SEND_FAILURE': return { ...state, sending: false, } case 'SMS/CREDIT_REQUEST': return { ...state, credit: '...' } case 'SMS/CREDIT_SUCCESS': return { ...state, credit: action.data } case 'SMS/CREDIT_FAILURE': return { ...state, credit: '?' } default: return state } } function * sendSMS (action) { try { const token = localStorage.getItem('accessToken') console.log('Send SMS requested', action, token) const { body, sender, recipients } = action.data const response = yield call(fetch, `${SZTM_API}/api/sms/send`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'x-access-token': token }, body: JSON.stringify({ recipients, body, sender }) }) if (response.status !== 200) { console.log(response) throw Error(yield response.json()) } else { const responseJson = yield response.json() yield put(actions.sendSMSSuccess(responseJson)) } } catch (error) { console.log('Config failure!', actions.sendSMSFailure(error.toString())) yield put(actions.sendSMSFailure(error)) } } function * getCredit (action) { console.log('getting credit.') yield put(api.actions.apiRequest({ path: 'api/sms/credits', onSuccess: actions.getCreditSuccess, onFailure: actions.getCreditFailure })) } /** sagas are asynchronous workers (JS generators) to handle the state. */ export function * saga () { console.log('SMS saga started.') yield takeEvery('SMS/SEND_REQUEST', sendSMS) yield takeEvery('SMS/CREDIT_REQUEST', getCredit) }