NotesWhat is notes.io?

Notes brand slogan

Notes - notes.io

import _ from 'lodash';
import { FilterButton, PageFilter } from '@components';
import { useImmer } from 'use-immer';
import { AppDropdown, AppIcon, DescriptionTableCell, RateTableCell, TagTableCell, TextTableCell } from '_/components';
import { Product, Question } from './state';
import { AppTable, AppTableToolbar, useAppTable, useAppTableColumn } from "_/components";
import Image from 'components/Image';
import { useTranslation } from 'react-i18next';
import { Button, Checkbox, Input, Progress, Collapse, TimePicker, Dropdown, Space, InputNumber, Tooltip, Radio, Pagination, Empty } from 'antd';
import { useHistory, useLocation } from "react-router-dom";
import styled from '@emotion/styled';
import { AppWrapper } from '_/components/app-skeleton';
import { Dispatch, SetStateAction, useEffect, useState } from 'react';
import { axiosInstance } from 'source/api';
import { useSelector } from 'react-redux';
import { State } from 'state';
import { useMutation } from 'react-query';
import { ClockCircleOutlined, CloseOutlined, DislikeOutlined, DownOutlined, LeftOutlined, RightOutlined, SearchOutlined, SortAscendingOutlined, SortDescendingOutlined, SwapOutlined } from '@ant-design/icons';
import moment from 'moment';
import { RetailerInfoTable } from './retailer-info-table';
import { InfoTable } from './info-table';
import { toast } from 'react-toastify';
import QuestionBot from 'assets/icons/QuestionBot';
import ConfirmPopover from './confirm';
const { Panel } = Collapse;
const { Search } = Input;

export interface QAProductProps {
questions: Question[];
setQuestions: Dispatch<SetStateAction<Question[]>>;
questionSort: 'newest' | 'oldest';
setQuestionSort: Dispatch<SetStateAction<'newest' | 'oldest'>>;
}

export const QAProducts = (props: QAProductProps) => {

let history = useHistory();
const location = useLocation();
const { t } = useTranslation()
const { session } = useSelector((x: State) => x.auth)
const {
questions,
setQuestions,
questionSort,
setQuestionSort
} = props;

const [confirmVisible, setConfirmVisible] = useState(false as any);
const [searchLoading, setSearchLoading] = useState(false);
const [searchText, setSearchText] = useState("");


const [filteredData, setFilteredData] = useState([]);
const [currentPage, setCurrentPage] = useState(1);
const [pageSize, setPageSize] = useState(2);
const [totalItems, setTotalItems] = useState(questions?.length);

const handlePaginationChange = (page, pageSize) => {
setCurrentPage(page);
};

const handleSearch = (value: string, sort: 'newest' | 'oldest') => {
if (value?.length > 0) {
setSearchLoading(true);
const barcode = new URLSearchParams(location.search).get('barcode');
const retailer_id = new URLSearchParams(location.search).get('retailerId');
axiosInstance.post('qa/questionsv3', {
retailer_id: parseInt(retailer_id), barcode, status: ["answered"], search: value?.length > 2 ? value : undefined, orderby: {
field: "question_time",
order: sort == "newest" ? "desc" : "asc",
}
})
.then((res) => {
setFilteredData(res.data.items);
setTotalItems(res.data.items.length + 1);
setCurrentPage(1);
setSearchLoading(false);
}).catch((e) => {
toast.error('Seach error. Please contact [email protected]');
});
} else {
setFilteredData(questions);
setTotalItems(questions?.length);
setCurrentPage(1);
}
};

const getCurrentPageData = () => {
const startIndex = (currentPage - 1) * pageSize;
const endIndex = startIndex + pageSize;
return filteredData?.slice(startIndex, endIndex) || [];
};

const handleSortClick = (e) => {
if (e.key === '1' && !searchLoading) {
setQuestionSort('newest');
handleSearch(searchText, 'newest')
}
else {
setQuestionSort('oldest');
handleSearch(searchText, 'oldest')


}
}

const { mutate, isLoading, error } = useMutation((data: { feedback: "dislike" | "ignore", question_id: string, expected_answer?: string }) => {

const { feedback, question_id, expected_answer } = data;
const retailer_id = new URLSearchParams(location.search).get('retailerId');

return axiosInstance.post('qa/post_question_feedback_v2', {
retailer_id,
feedback,
question_id,
expected_answer: feedback == "dislike" ? expected_answer : undefined
}).then((res) => {
setQuestions(questions.map((e) => {
if (e.question_id == question_id) {
return { ...e, feedback: feedback, expected_answer: expected_answer || null }
}
return e;
}))
}).catch((e) => {
console.log(e);
toast.error(t('An problem occurred while trying to give feedback to an answer. Please contact [email protected]'))
});
});

return <div className="qa-past-questions">
<h1>{t("Evaluate Past Question Answers")}</h1>

<div className="qa-past-questions-info" >
<InfoIcon />
<p>{t(`You can help us produce better answers by evaluating past questions and answers about your product. The Q&A system will remember your preferences.`)}</p>
</div>
<div className="qa-past-questions-filter" >
<Dropdown menu={{
items: [
{
label: t('Newest'),
key: '1',
icon: <SortAscendingOutlined />,
},
{
label: t('Oldest'),
key: '2',
icon: <SortDescendingOutlined />,
}
],
onClick: handleSortClick,
}}>
<Button>
<Space>
{questionSort == "newest" ? <>
{t("Newest")}
<SortAscendingOutlined />
</> : <>
{t("Oldest")}
<SortDescendingOutlined />
</>}
</Space>
</Button>
</Dropdown>
<Search value={searchText} onChange={(e) => { setSearchText(e.target.value) }} disabled={searchLoading} loading={searchLoading} placeholder={t("Search")} onSearch={(e) => { handleSearch(e, questionSort); }} style={{ width: 270 }} />
</div>
<div className="qa-past-questions-container" >
{getCurrentPageData()?.length > 1 ? getCurrentPageData().map((e: Question, i) => (<div key={i} className="past-question" >
<div className="past-question-header">
<h1>{e?.question}</h1>
</div>
<div className="past-question-body">
<div className="past-question-answer">
<span className='answer' >{e?.answer}</span>
<div className="past-question-footer">
<div className='past-question-actions' >
{/* <Radio.Group size='medium' >
<Radio.Button disabled={isLoading} onClick={() => { mutate({ feedback: "dislike", question_id: e.question_id }) }} ><AppIcon type='thumbs_down' /></Radio.Button>
<Radio.Button disabled={isLoading} onClick={() => { mutate({ feedback: "ignore", question_id: e.question_id }) }} ><AppIcon type='x' /></Radio.Button>
</Radio.Group>
*/}
{e.feedback ?
<div className="past-btn-group-feedback">
{e.feedback == "dislike" && <Tooltip placement="top" title={t("Disliked")} >
<Button className='m-0' size='small' disabled ><AppIcon size={16} type='thumbs_down' /></Button>
</Tooltip>}
{e.feedback == "ignore" && <Tooltip placement="top" title={t("Ignored")} >
<Button className='m-0' size='small' disabled ><AppIcon size={16} type='x' /></Button>
</Tooltip>
}
</div>
:
<div className="past-btn-group">
<ConfirmPopover
visible={confirmVisible}
setVisible={setConfirmVisible}
onConfirm={(text) => {
mutate({ feedback: "dislike", question_id: e.question_id, expected_answer: text })
}}
question_id={e.question_id}
>
<Tooltip placement="top" title={t("Dislike")} >
<Button className='dislike-btn' size='small' disabled={isLoading} onClick={() => { setConfirmVisible(e.question_id) }} ><AppIcon size={16} type='thumbs_down' /></Button>
</Tooltip>
</ConfirmPopover>

<Tooltip placement="top" title={t("Ignore")} >
<Button className='ignore-btn' size='small' disabled={isLoading} onClick={() => { mutate({ feedback: "ignore", question_id: e.question_id }) }} ><AppIcon size={16} type='x' /></Button>
</Tooltip>
</div>
}
</div>
<div className='past-question-date' >
{e.answered_by == "dotbot" && <>
<QuestionBot />
<span className='dot-text' >{t("Answered by Dot")}</span>
<span className='dot' ></span>
</>}
<span className='date' >{moment(e?.question_time).format('DD.MM.yyyy , H:m')}</span>
</div>
</div>
</div>
</div>
</div>)) : <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />}
</div>
<div className='d-flex align-items-center justify-content-end w-100' >
<Pagination
current={currentPage}
pageSize={pageSize}
total={totalItems}
onChange={handlePaginationChange}
showSizeChanger={false}
/>
</div>
</div >



}

const InfoIcon = () => {
return <svg xmlns="http://www.w3.org/2000/svg" width="21" height="21" viewBox="0 0 21 21" fill="none">
<g clip-path="url(#clip0_11608_36915)">
<path d="M10.4998 2.56665C15.1023 2.56665 18.8332 6.29748 18.8332 10.9C18.8349 13.0879 17.9761 15.1887 16.4423 16.7489C14.9084 18.309 12.8225 19.2034 10.6349 19.2388C8.44725 19.2743 6.33345 18.448 4.74984 16.9383C3.16622 15.4287 2.23983 13.3568 2.17067 11.17L2.1665 10.9L2.16984 10.6667C2.29317 6.17248 5.97484 2.56665 10.4998 2.56665ZM10.4998 10.0667H9.6665L9.569 10.0725C9.36646 10.0966 9.17979 10.1941 9.04435 10.3466C8.90891 10.4991 8.8341 10.696 8.8341 10.9C8.8341 11.104 8.90891 11.3008 9.04435 11.4533C9.17979 11.6059 9.36646 11.7034 9.569 11.7275L9.6665 11.7333V14.2333L9.67234 14.3308C9.69427 14.5168 9.77824 14.69 9.91068 14.8225C10.0431 14.9549 10.2163 15.0389 10.4023 15.0608L10.4998 15.0667H11.3332L11.4307 15.0608C11.6167 15.0389 11.7899 14.9549 11.9223 14.8225C12.0548 14.69 12.1387 14.5168 12.1607 14.3308L12.1665 14.2333L12.1607 14.1358C12.1407 13.9658 12.069 13.806 11.955 13.6783C11.8411 13.5505 11.6906 13.4609 11.524 13.4216L11.4307 13.405L11.3332 13.4V10.9L11.3273 10.8025C11.3054 10.6165 11.2214 10.4433 11.089 10.3108C10.9566 10.1784 10.7834 10.0944 10.5973 10.0725L10.4998 10.0667ZM10.5082 7.56665L10.4023 7.57248C10.1998 7.59658 10.0131 7.69411 9.87768 7.84662C9.74224 7.99913 9.66743 8.19601 9.66743 8.39998C9.66743 8.60395 9.74224 8.80084 9.87768 8.95335C10.0131 9.10585 10.1998 9.20339 10.4023 9.22748L10.4998 9.23332L10.6057 9.22748C10.8082 9.20339 10.9949 9.10585 11.1303 8.95335C11.2658 8.80084 11.3406 8.60395 11.3406 8.39998C11.3406 8.19601 11.2658 7.99913 11.1303 7.84662C10.9949 7.69411 10.8082 7.59658 10.6057 7.57248L10.5082 7.56665Z" fill="#FF8808" />
</g>
<defs>
<clipPath id="clip0_11608_36915">
<rect width="20" height="20" fill="white" transform="translate(0.5 0.899902)" />
</clipPath>
</defs>
</svg>
}
     
 
what is notes.io
 

Notes.io is a web-based application for taking notes. You can take your notes and share with others people. If you like taking long notes, notes.io is designed for you. To date, over 8,000,000,000 notes created and continuing...

With notes.io;

  • * You can take a note from anywhere and any device with internet connection.
  • * You can share the notes in social platforms (YouTube, Facebook, Twitter, instagram etc.).
  • * You can quickly share your contents without website, blog and e-mail.
  • * You don't need to create any Account to share a note. As you wish you can use quick, easy and best shortened notes with sms, websites, e-mail, or messaging services (WhatsApp, iMessage, Telegram, Signal).
  • * Notes.io has fabulous infrastructure design for a short link and allows you to share the note as an easy and understandable link.

Fast: Notes.io is built for speed and performance. You can take a notes quickly and browse your archive.

Easy: Notes.io doesn’t require installation. Just write and share note!

Short: Notes.io’s url just 8 character. You’ll get shorten link of your note when you want to share. (Ex: notes.io/q )

Free: Notes.io works for 12 years and has been free since the day it was started.


You immediately create your first note and start sharing with the ones you wish. If you want to contact us, you can use the following communication channels;


Email: [email protected]

Twitter: http://twitter.com/notesio

Instagram: http://instagram.com/notes.io

Facebook: http://facebook.com/notesio



Regards;
Notes.io Team

     
 
Shortened Note Link
 
 
Looding Image
 
     
 
Long File
 
 

For written notes was greater than 18KB Unable to shorten.

To be smaller than 18KB, please organize your notes, or sign in.