diff --git a/package.json b/package.json index 3803d13d..77116a05 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "@testing-library/react": "^11.1.0", "@testing-library/user-event": "^12.1.10", "axios": "^0.21.4", + "moment": "^2.29.1", "consul": "^0.40.0", "express": "^4.17.1", "properties-reader": "^0.3.1", diff --git a/src/App.js b/src/App.js index aa9d258d..3bb61628 100644 --- a/src/App.js +++ b/src/App.js @@ -5,6 +5,7 @@ import HomeContainer from './pages/home/HomePage'; import ProductDetails from './pages/product-details/ProductDetails'; import SearchContainer from './pages/sku-search/SearchPage'; import ProductInfo from './pages/product-info/ProductInfo'; +import QuestionAndAnswer from './pages/sku-q&a/QuestionAndAnswer'; import ProductVariants from './pages/product-variants/ProductVariants'; import store from './store'; import Header from './components/header/Header'; @@ -47,6 +48,11 @@ const App = () => { path='/product-variants/:id/:defaultProduct' component={ProductVariants} /> + diff --git a/src/__tests__/pages/sku-q&a/q&aTitle/QATile.test.js b/src/__tests__/pages/sku-q&a/q&aTitle/QATile.test.js new file mode 100644 index 00000000..8bdb6ab7 --- /dev/null +++ b/src/__tests__/pages/sku-q&a/q&aTitle/QATile.test.js @@ -0,0 +1,91 @@ +import { render, screen } from '@testing-library/react'; +import QATile from '../../../../pages/sku-q&a/q&aTile/QATile'; +import moment from 'moment'; +const mockData = { + ugc_id: 380507831, + question_id: '8123156', + details: { + nickname: 'migb', + created_date: 1629812604000, + text: 'How do you clean these before reusing?', + location: 'Ashtabula, OH', + product_page_id: '11014345', + is_seeded: false, + }, + answer: [ + { + ugc_id: 380510586, + answer_id: '7169235', + details: { + nickname: 'beneel', + location: 'USA', + text: 'These bags can hand-washing.', + is_verified: true, + is_expert: false, + author_type: 'COMMUNITY', + created_date: 1631382272000, + }, + metrics: { + helpful_votes: 0, + not_helpful_votes: 0, + }, + }, + ], + answer_count: 2, +}; +const askerName = mockData.details.nickname; +const askerTime = moment(mockData.details.created_date).fromNow(); +const question = mockData.details.text; +const answererName = mockData.answer[0].details.nickname; +const answererTime = moment(mockData.answer[0].details.created_date).fromNow(); +const answer = mockData.answer[0].details.text; +let askerNameText; +let questionTimeText; +let questionText; +let answererNameText; +let answerTimeText; +let answerText; +describe('Testing Search Bar component', () => { + test('inital Render Condition', () => { + render(); + + askerNameText = screen.getByText(askerName, { + exact: false, + }); + expect(askerNameText).toHaveTextContent(askerName); + + questionTimeText = screen.getByText(askerTime); + expect(questionTimeText).toHaveTextContent(askerTime); + + questionText = screen.getByText(question, { + exact: false, + }); + expect(questionText).toHaveTextContent(question); + + answererNameText = screen.getByText(answererName, { + exact: false, + }); + expect(answererNameText).toHaveTextContent(answererName); + + answerTimeText = screen.getByText(answererTime); + expect(answerTimeText).toHaveTextContent(answererTime); + + answerText = screen.getByText(answer, { + exact: false, + }); + expect(answerText).toHaveTextContent(answer); + }); + + test('view more answer text should be displayed when multiple answer will be available', () => { + render(); + const viewMoreAnswerText = screen.getByText( + `View ${parseInt(mockData.answer.length - 1)} More Answers`, + { + exact: false, + } + ); + expect(viewMoreAnswerText).toHaveTextContent( + `View ${parseInt(mockData.answer.length - 1)} More Answers` + ); + }); +}); diff --git a/src/config.js b/src/config.js index 49863064..36004cf2 100644 --- a/src/config.js +++ b/src/config.js @@ -1,21 +1,21 @@ -import { fetchAppConfig } from "./services/config.service"; +import { fetchAppConfig } from './services/config.service'; -export const getConfig = key => global.appConfig[key] +export const getConfig = (key) => global.appConfig[key]; -const setConfig = data => { - global.appConfig = data; -} +const setConfig = (data) => { + global.appConfig = data; +}; export const initializeAppConfig = () => { - return fetchAppConfig() - .then(res=>{ - setConfig(res?.data); - return res.data; + return fetchAppConfig() + .then((res) => { + setConfig(res?.data); + return res.data; }) - .catch(err => { - console.log("FAILED TO FETCH APP_CONFIG"); - throw err; - }) -} + .catch((err) => { + console.log('FAILED TO FETCH APP_CONFIG'); + throw err; + }); +}; export default global.appConfig; diff --git a/src/pages/product-details/ProductDetails.js b/src/pages/product-details/ProductDetails.js index ab807e87..d43025aa 100644 --- a/src/pages/product-details/ProductDetails.js +++ b/src/pages/product-details/ProductDetails.js @@ -97,7 +97,7 @@ const ProductDetails = ({ history, match }) => { if (skuData?.id !== Number(match?.params?.id)) { dispatch(fetchSkuDetails(match?.params?.id, storeId)); } - }, [dispatch, match?.params?.id, skuData,storeId]); + }, [dispatch, match?.params?.id, skuData, storeId]); const toggleDrawer = (open) => { open && dispatch(fetchStoreAvailability(match?.params?.id, storeId)); @@ -175,7 +175,7 @@ const ProductDetails = ({ history, match }) => { o.name === 'SKU_IMAGE') + ?.filter((o) => o.name === 'large') ?.map((o) => `${ASSET_URL}${o.url}`) || [] } /> @@ -189,8 +189,8 @@ const ProductDetails = ({ history, match }) => { Was ${skuPriceDetails?.price} - Save ${skuPriceDetails?.maxSavings} ({skuPriceDetails?.maxPercentOff} - % off) + Save ${skuPriceDetails?.maxSavings} ( + {skuPriceDetails?.maxPercentOff}% off) @@ -307,6 +307,12 @@ const ProductDetails = ({ history, match }) => { Additional Sizes & Colors + history.push(`/sku-info/q&a/${match?.params?.id}`)} + > + Q&A + + ); diff --git a/src/pages/product-variants/ProductVariants.js b/src/pages/product-variants/ProductVariants.js index c87a4d5f..3cda3451 100644 --- a/src/pages/product-variants/ProductVariants.js +++ b/src/pages/product-variants/ProductVariants.js @@ -9,9 +9,9 @@ import { PageContainer, Title, ErrorWrapper, - NoContent + NoContent, } from './ProductVariants.styles'; -import { getSkuPrice, getQtyInStore } from './../../utils/skuHelpers'; +import { getQtyInStore, getSkuPriceDetails } from './../../utils/skuHelpers'; import SkuError from '../../components/sku-error/SkuError'; import { getConfig } from './../../config'; import { skuErrorMessages } from '../../constants/errorMessages'; @@ -51,17 +51,19 @@ const ProductVariants = ({ history, match }) => { useEffect(() => { dispatch(fetchSkuVariants(match?.params?.defaultProduct, storeId)); - }, [dispatch, match?.params?.defaultProduct,storeId]); + }, [dispatch, match?.params?.defaultProduct, storeId]); useEffect(() => { - if (skuData?.id !== Number(match?.params?.id)) dispatch(fetchSkuDetails(match?.params?.id, storeId, false)); - }, [dispatch, match?.params?.id, skuData,storeId]); + if (skuData?.id !== Number(match?.params?.id)) { + dispatch(fetchSkuDetails(match?.params?.id, storeId, false)); + } + }, [dispatch, match?.params?.id, skuData, storeId]); const getSkuData = (item) => { const ASSET_URL = getConfig('asset_base_url'); const skuInfo = { image: `${ASSET_URL}${item.mediaList?.[0]?.url}`, - price: getSkuPrice(item?.productPrice, 'maxRetailPrice'), + skuPriceDetails: getSkuPriceDetails(skuData?.skuPrices), name: item.name, qtyAvailableAtStore: getQtyInStore( skuAvailability?.inventoryEstimates, @@ -92,34 +94,32 @@ const ProductVariants = ({ history, match }) => { ratingCount={10} /> )} - - Additional Sizes & Colors{' '} - {variants?.length ? `(${variants.length})` : null} - + + Additional Sizes & Colors{' '} + {variants?.length ? `(${variants.length})` : null} + {/* */} - { - loading ? ( - Array(2) - .fill(null) - .map((_, i) => ) - ) : variants?.length ? ( - variants.map((item, i) => { - const skuInfo = getSkuData(item); - return ( - history.push(`/product-details/${id}`)} - /> - ); - }) - ) : ( - {skuErrorMessages.productVariants.title} - // - ) - } + {loading ? ( + Array(2) + .fill(null) + .map((_, i) => ) + ) : variants?.length ? ( + variants.map((item, i) => { + const skuInfo = getSkuData(item); + return ( + history.push(`/product-details/${id}`)} + /> + ); + }) + ) : ( + {skuErrorMessages.productVariants.title} + // + )} {/* */} ); diff --git a/src/pages/sku-q&a/QuestionAndAnswer.js b/src/pages/sku-q&a/QuestionAndAnswer.js new file mode 100644 index 00000000..eabb3880 --- /dev/null +++ b/src/pages/sku-q&a/QuestionAndAnswer.js @@ -0,0 +1,186 @@ +import React, { useEffect, useState } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import { + fetchQuestionDetails, + fetchQuestionSortByDetails, + fetchQuestionByPage, +} from '../../slices/q&a.slice'; +import { fetchSkuDetails } from '../../slices/sku.slice'; +import SkuError from '../../components/sku-error/SkuError'; +import ProductTitle from '../../components/product-title/ProductTitle'; +import QATile from './q&aTile/QATile'; +import { MenuItem, Typography } from '@mui/material'; +import { + BoxWrapper, + SelectWrapper, + ButtonWrapper, + ErrorWrapper, + SKUNameSkeletion, + QATextSkeletion, + NoOfQuestionTextSkeletion, + SortBySkeletion, +} from './QuestionAndAnswer.styles'; +import QATileLoadingSkeletion from './q&aTile/QATileLoadingSkeletion'; +import { Box } from '@mui/system'; +import Skeleton from '@mui/material/Skeleton'; +import { skuErrorMessages } from '../../constants/errorMessages'; +const options = [ + { + name: 'Newest', + value: 'Newest', + }, + { + name: 'Oldest', + value: 'Oldest', + }, + { + name: 'Most Answer', + value: 'MostAnswers', + }, +]; +const getRemainingQuestions = (remainingQuestions) => { + return remainingQuestions > 10 ? 10 : remainingQuestions; +}; +const LoadingSkeleton = () => { + return ( + + + + + + + + + + + + + + ); +}; +function QuestionAndAnswer({ match }) { + const dispatch = useDispatch(); + const { + skuData, + error: skuError, + storeId, + loading: skuLoading, + } = useSelector((state) => state.sku); + const { loading, questionsData, error } = useSelector( + (state) => state.skuQuestions + ); + const [selectedOption, setSelectedOption] = useState(options[0].name); + const [showingQuestions, setShowingQuestions] = useState(3); + const [remainingQuestions, setRemainingQuestions] = useState(0); + + useEffect(() => { + if (skuData?.id !== Number(match?.params?.id)) { + dispatch(fetchSkuDetails(match?.params?.id, storeId)); + } + }, [dispatch, match?.params?.id, skuData, storeId]); + + useEffect(() => { + if (skuData != null) { + dispatch(fetchQuestionDetails(skuData?.defaultProductId)); + } + }, [dispatch, skuData]); + + useEffect(() => { + if (questionsData != null) { + setRemainingQuestions( + questionsData?.paging.total_results - + questionsData?.results.slice(0, showingQuestions).length + ); + } + }, [showingQuestions, questionsData]); + + const moreQuestionClickHandler = () => { + if (questionsData?.paging?.next_page_url != null) { + dispatch( + fetchQuestionByPage( + questionsData?.paging?.next_page_url, + questionsData?.results + ) + ); + } + setShowingQuestions((prevState) => prevState + 10); + }; + const sortByClickHandler = (e) => { + setSelectedOption(e.target.value); + dispatch( + fetchQuestionSortByDetails(skuData?.defaultProductId, e.target.value) + ); + }; + + if (error || skuError) { + return ( + + {error ? ( + + ) : ( + + )} + + ); + } + if (skuLoading) { + return ; + } + return ( + + + Q&A + + {loading ? ( + + ) : ( + `1-${questionsData?.results.slice(0, showingQuestions).length} of + ${questionsData?.paging.total_results} Question` + )} + + + {options.map((option) => ( + + {option.name} + + ))} + + {loading && ( + <> + + + + + )} + {questionsData?.results + .slice(0, showingQuestions) + .map((questionInfo, index) => ( + + ))} + {loading && } + {remainingQuestions > 0 ? ( + <> + + {remainingQuestions} More Questions + + + `VIEW NEXT ${getRemainingQuestions(remainingQuestions)} QUESTIONS` + + + ) : null} + +
+
+ ); +} + +export default QuestionAndAnswer; diff --git a/src/pages/sku-q&a/QuestionAndAnswer.styles.js b/src/pages/sku-q&a/QuestionAndAnswer.styles.js new file mode 100644 index 00000000..69cc95a0 --- /dev/null +++ b/src/pages/sku-q&a/QuestionAndAnswer.styles.js @@ -0,0 +1,82 @@ +import { styled } from '@mui/styles'; +import { Box } from '@mui/system'; +import Select from '@mui/material/Select'; +import { colors } from '../../utils/themeUtils'; +import Button from '@mui/material/Button'; +import Skeleton from '@mui/material/Skeleton'; +export const BoxWrapper = styled(Box)({ + padding: '8px 15px 0px 15px', + '& .text': { + fontSize: '18px', + lineHeight: '22px', + fontWeight: '700', + color: colors.fontColor, + marginTop: '25px', + }, + '& .total-question': { + fontSize: '16px', + fontWeight: '400', + color: colors.black, + margin: '16px 0px', + }, + '& .more-question-test': { + fontsize: '14px', + lineHeight: '17px', + color: colors.black, + fontWeight: 'bold', + textAlign: 'center', + marginTop: '16px', + }, + '& .select': { + border: '1px solid red', + }, + '& hr': { + border: `1px solid ${colors.gray85}`, + }, +}); + +export const SelectWrapper = styled(Select)({ + height: '42px', + display: 'flex', + flexGrow: '1', + boxSizing: 'border-box', + border: `1px solid ${colors.black}`, + borderRadius: '4px', + marginBottom: '16px', + '& fieldset': { + border: 'none', + }, +}); + +export const ButtonWrapper = styled(Button)({ + height: '48px', + marginTop: '24px', + color: colors['primary-blue'], + border: `2px solid ${colors['primary-blue']}`, + textTransform: 'capitalize', + width: '100%', + marginBottom: '33px', +}); + +export const ErrorWrapper = styled(Box)({ + padding: '29px 0px', +}); + +export const SKUNameSkeletion = styled(Skeleton)({ + fontSize: '16px', + marginBottom: '2px', +}); + +export const QATextSkeletion = styled(Skeleton)({ + marginTop: '25px', + fontSize: '18px', +}); + +export const NoOfQuestionTextSkeletion = styled(Skeleton)({ + marginTop: '16px', + fontSize: '16px', +}); + +export const SortBySkeletion = styled(Skeleton)({ + marginTop: '0px 16px', +}); diff --git a/src/pages/sku-q&a/q&aTile/QATile.js b/src/pages/sku-q&a/q&aTile/QATile.js new file mode 100644 index 00000000..67ee6592 --- /dev/null +++ b/src/pages/sku-q&a/q&aTile/QATile.js @@ -0,0 +1,49 @@ +import React, { useEffect, useState } from 'react'; +import { Typography } from '@mui/material'; +import { BoxWrapper, Asker, Question, Answer } from './QATile.styles'; +import moment from 'moment'; +function QATile({ questionInfo, i }) { + const { answer, details } = questionInfo; + const [answers, setAnswers] = useState([]); + + useEffect(() => { + setAnswers(answer?.slice(0, 1)); + }, [answer]); + const viewMoreClick = () => { + setAnswers(answer); + }; + return ( + + + {details?.nickname} ·  + + {moment(details?.created_date).fromNow()} + + + + {i + 1}. {details?.text} + + {answers?.map((data) => ( + + + + {data?.details?.nickname} · + + {moment(data?.details?.created_date).fromNow()} + + + {data?.details?.text} + + + ))} + + {answer.length === answers.length ? null : ( + + View {answer?.length - answers?.length} More Answers + + )} + + ); +} + +export default QATile; diff --git a/src/pages/sku-q&a/q&aTile/QATile.styles.js b/src/pages/sku-q&a/q&aTile/QATile.styles.js new file mode 100644 index 00000000..75c9bf31 --- /dev/null +++ b/src/pages/sku-q&a/q&aTile/QATile.styles.js @@ -0,0 +1,69 @@ +import { Typography } from '@mui/material'; +import { styled } from '@mui/styles'; +import { Box } from '@mui/system'; +import { colors } from '../../../utils/themeUtils'; + +export const LoadingBoxWrapper = styled(Box)({ + padding: '24px', + border: `1px solid ${colors.qaTileBorder}`, + '& .asker': { + marginBottom: '8px', + }, + '& .question': { + marginBottom: '16px', + }, + '& .view-more-answerer': { + marginTop: '16px', + }, + marginBottom: '16px', +}); + +export const BoxWrapper = styled(Box)({ + padding: '23px', + border: `1px solid ${colors.qaTileBorder}`, + '& .view-more-answerer': { + color: colors.primary, + fontsize: '14px', + lineHeight: '18px ', + marginTop: '16px', + textDecoration: 'underline', + }, + marginBottom: '16px', +}); + +export const Asker = styled(Typography)({ + fontSize: '14px', + color: colors.primary, + marginBottom: '8px', + textTransform: 'capitalize', +}); + +export const Question = styled(Typography)({ + fontSize: '18px', + lineHeight: '22px', + fontWeight: 'bold', + color: colors.black, + marginBottom: '16px', + wordBreak: 'break-all', +}); + +export const Answer = styled(Box)({ + backgroundColor: colors.answerBackground, + padding: '16px', + '& .answerer': { + fontSize: '16px', + lineHeight: '24px', + fontWeight: '400', + color: colors.black, + marginBottom: '8px', + textTransform: 'capitalize', + }, + '& .answerer-text': { + fontSize: '16px', + lineHeight: '20px', + fontWeight: '400', + color: colors.black, + wordBreak: 'break-all', + }, + marginBottom: '8px', +}); diff --git a/src/pages/sku-q&a/q&aTile/QATileLoadingSkeletion.js b/src/pages/sku-q&a/q&aTile/QATileLoadingSkeletion.js new file mode 100644 index 00000000..1de510d7 --- /dev/null +++ b/src/pages/sku-q&a/q&aTile/QATileLoadingSkeletion.js @@ -0,0 +1,24 @@ +import React from 'react'; +import Skeleton from '@mui/material/Skeleton'; +import { LoadingBoxWrapper, Answer } from './QATile.styles'; +function QATileLoadingSkeletion() { + return ( + + + + + + + + + + + + + + + + ); +} + +export default QATileLoadingSkeletion; diff --git a/src/services/q&a.service.js b/src/services/q&a.service.js new file mode 100644 index 00000000..0ef8eecb --- /dev/null +++ b/src/services/q&a.service.js @@ -0,0 +1,25 @@ +import Axios from '../api'; +import { getConfig } from '../config'; + +export const getQuestionsData = (productID) => { + const POWER_REVIEW_URL = getConfig('power_review_url'); + const MERCAHANT_ID = getConfig('merchant_id'); + const POWER_REVIEW_API_KEY = getConfig('power_review_api_key'); + const url = `${POWER_REVIEW_URL}/m/${MERCAHANT_ID}/l/en_US/product/${productID}/questions?_noconfig=true&apikey=${POWER_REVIEW_API_KEY}`; + return Axios.get(url); +}; + +export const getQuestionsDataSortBy = (productID, sortBy) => { + const POWER_REVIEW_URL = getConfig('power_review_url'); + const MERCAHANT_ID = getConfig('merchant_id'); + const POWER_REVIEW_API_KEY = getConfig('power_review_api_key'); + const url = `${POWER_REVIEW_URL}/m/${MERCAHANT_ID}/l/en_US/product/${productID}/questions?sort=${sortBy}&_noconfig=true&apikey=${POWER_REVIEW_API_KEY}`; + return Axios.get(url); +}; + +export const getQuestionDataByPage = (nextPageURL) => { + const POWER_REVIEW_URL = getConfig('power_review_url'); + const POWER_REVIEW_API_KEY = getConfig('power_review_api_key'); + const url = `${POWER_REVIEW_URL}${nextPageURL}&apikey=${POWER_REVIEW_API_KEY}`; + return Axios.get(url); +}; diff --git a/src/slices/q&a.slice.js b/src/slices/q&a.slice.js new file mode 100644 index 00000000..93b7757c --- /dev/null +++ b/src/slices/q&a.slice.js @@ -0,0 +1,74 @@ +import * as questionService from '../services/q&a.service'; +import { createSlice } from '@reduxjs/toolkit'; +const INITIAL_STATE = { + loading: false, + questionsData: null, + error: null, +}; + +const questionSlice = createSlice({ + name: 'questions', + initialState: INITIAL_STATE, + reducers: { + questionsLoading: (state) => { + state.loading = true; + }, + questionsSuccess: (state, action) => { + state.loading = false; + state.questionsData = action.payload; + }, + questionsPageSuccess: (state, action) => { + state.loading = false; + state.questionsData = action.payload; + }, + questionsFailure: (state, action) => { + state.loading = false; + state.error = action.payload; + }, + }, +}); + +const actions = questionSlice.actions; + +export const fetchQuestionDetails = (productID) => (dispatch) => { + dispatch(actions.questionsLoading()); + questionService + .getQuestionsData(productID) + .then((res) => { + dispatch(actions.questionsSuccess(res?.data)); + }) + .catch((err) => { + dispatch(actions.questionsFailure(err)); + }); +}; + +export const fetchQuestionSortByDetails = (productID, sortBy) => (dispatch) => { + dispatch(actions.questionsLoading()); + questionService + .getQuestionsDataSortBy(productID, sortBy) + .then((res) => { + dispatch(actions.questionsSuccess(res?.data)); + }) + .catch((err) => { + dispatch(actions.questionsFailure(err)); + }); +}; + +export const fetchQuestionByPage = (nextPageURL, results) => (dispatch) => { + dispatch(actions.questionsLoading()); + questionService + .getQuestionDataByPage(nextPageURL) + .then((res) => { + dispatch( + actions.questionsPageSuccess({ + ...res?.data, + results: [...results, ...res?.data.results], + }) + ); + }) + .catch((err) => { + dispatch(actions.questionsFailure(err)); + }); +}; + +export default questionSlice; diff --git a/src/store/rootReducer.js b/src/store/rootReducer.js index 38651777..7d3f1e0e 100644 --- a/src/store/rootReducer.js +++ b/src/store/rootReducer.js @@ -4,10 +4,11 @@ import currencySlice from '../slices/currency.slice'; import skuSlice from '../slices/sku.slice'; import spinnerSlice from '../slices/spinner.slice'; import skuVariants from '../slices/skuVariants.slice'; - +import skuQuestions from '../slices/q&a.slice'; export default combineReducers({ currency: currencySlice.reducer, sku: skuSlice.reducer, spinner: spinnerSlice.reducer, skuVariants: skuVariants.reducer, + skuQuestions: skuQuestions.reducer, }); diff --git a/src/utils/MockData.js b/src/utils/MockData.js index 25880219..f539835a 100644 --- a/src/utils/MockData.js +++ b/src/utils/MockData.js @@ -1,4 +1,3 @@ - export const skuAvailability = { requestStoreNumber: '5', inventoryEstimates: [ @@ -52,3 +51,4 @@ export const skuAvailability = { }, ], }; + diff --git a/src/utils/skuHelpers.js b/src/utils/skuHelpers.js index 3359a22e..b5abc379 100644 --- a/src/utils/skuHelpers.js +++ b/src/utils/skuHelpers.js @@ -29,3 +29,15 @@ export const getQtyInDC = (data = [], storeId) => ?.qtyAvailableInDc; export const getQtyOnline = (data = []) => data?.find((o) => o.fulfillmentStoreNumber === '899')?.qtyAvailableInDc; + +export const filterQuestionsData = (questionData, newQuestions) => { + console.log(questionData); + console.log(newQuestions); + return { + ...newQuestions, + questionData: { + ...newQuestions.questionData, + results: [...questionData.results, ...newQuestions.questionData.results], + }, + }; +}; diff --git a/src/utils/themeUtils.js b/src/utils/themeUtils.js index b657fe70..da513869 100644 --- a/src/utils/themeUtils.js +++ b/src/utils/themeUtils.js @@ -14,4 +14,7 @@ export const colors = { dangerBackground: '#FDF4F5', dangerBorder: 'rgba(223, 46, 47, 0.1)', spinnerBackground: '#2e50a7', + qaTileBorder: '#EAEBEF', + answerBackground: '#F6F6FA', + 'primary-blue': '#039BE5', }; diff --git a/yarn.lock b/yarn.lock index 4fd873c4..8cdcd45c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8178,6 +8178,11 @@ mkdirp@^1.0.3, mkdirp@^1.0.4: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== +moment@^2.29.1: + version "2.29.1" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3" + integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ== + move-concurrently@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92"