diff --git a/src/components/BottomSheetComponents/Ticket.js b/src/components/BottomSheetComponents/Ticket.js new file mode 100644 index 0000000..417c58d --- /dev/null +++ b/src/components/BottomSheetComponents/Ticket.js @@ -0,0 +1,160 @@ +import React, { useMemo, useEffect, useCallback } from "react"; +import { ScrollView, Appearance, View } from "react-native"; +import { connect } from "react-redux"; +import { userProduct, comment, file, form } from "../../redux/actions"; +import onInput from "../../utils/onInput"; + +//components +import CustomTextInput from "../CustomTextInput"; +import CustomPressable from "../Pressable"; +import Select from "../Select"; + +//style +import tw from "tailwind-rn"; +import Colors from "../../constants/Colors"; +import fontSize from "../../constants/fontSize"; + +export const Ticket = ({ + myProductList, + status, + ticket, + getUserProductList, + submit, + upload, + setTicket, + grades, +}) => { + const colorScheme = Appearance.getColorScheme(); + let opt = useMemo( + () => ["واحد مورد نظر", "واحد فروش", "واحد فنی", "واحد محتوایی"], + [status] + ); + + useEffect(() => { + if (myProductList.length === 0 && status) { + getUserProductList(); + } + }, []); + + const send = useCallback(async () => { + if (!ticket?.subject) { + setDialog({ + text: "موضوع پیام خود را وارد کنید.", + type: "alert", + accept: () => {}, + open: true, + }); + } else if (!ticket?.unit) { + setDialog({ + text: "واحد مورد نظر خود را وارد نکرده اید.", + type: "alert", + accept: () => {}, + open: true, + }); + } else { + const data = { + fileId: null, + text: ticket?.text, + name: !status ? ticket?.name : status.firstName + " " + status.lastName, + cellphone: !status ? ticket?.cellphone : status?.cellphone, + unit: ticket?.unit, + bookId: ticket?.bookId, + subject: ticket?.subject, + userId: status?.userId, + }; + await submit(data); + } + }, [status]); + + return ( + + + {!status && ( + <> + setTicket({ name, value })} + value={ticket?.name || ""} + regex={(val) => val} + /> + setTicket({ name, value })} + value={ticket?.cellphone || ""} + regex={(val) => onInput.phonenumber(val)} + maxLength="11" + /> + + )} + [ + item?.product?.book?.id, + `${item?.product?.book.name} پایه ${ + Object.values(grades)[item.product.book.gradeId] + }`, + ]) || [] + ), + ]} + onChange={(name, value) => setTicket({ name, value })} + width={"100%"} + /> + )} + setTicket({ name, value })} + value={ticket?.subject || ""} + regex={(val) => val} + label="موضوع" + /> + setTicket({ name, value })} + value={ticket?.text || ""} + regex={(val) => val} + label="متن پیام" + multiline={true} + /> + + + send()} + /> + + ); +}; + +const mapStateToProps = (state) => ({ + isDark: state.publicApi.isDark, + myProductList: state.userProduct.myList, + status: state.user.status, + ticket: state.form.ticket, + grades: state.publicApi.grades, +}); + +const mapDispatchToProps = { + getUserProductList: userProduct.myList, + submit: comment.add, + upload: file.upload, + setTicket: form.setTicket, +}; + +export default connect(mapStateToProps, mapDispatchToProps)(Ticket); diff --git a/src/components/CustomTextInput.js b/src/components/CustomTextInput.js index 633eaa4..59583e0 100644 --- a/src/components/CustomTextInput.js +++ b/src/components/CustomTextInput.js @@ -31,6 +31,7 @@ const FloatingLabelInput = ({ regex, mobile, keyboardType, + multiline, ...props }) => { const colorScheme = useColorScheme(); @@ -96,6 +97,7 @@ const FloatingLabelInput = ({ value={value} onBlur={() => (value ? {} : setIsFocused(() => false))} keyboardType={keyboardType} + multiline={multiline} /> ); diff --git a/src/redux/actions/comment.js b/src/redux/actions/comment.js new file mode 100644 index 0000000..d1b2c30 --- /dev/null +++ b/src/redux/actions/comment.js @@ -0,0 +1,32 @@ +import proxy from "../proxy"; +const comment = { + list: + (data = {}) => + async (dispatch) => + await proxy.get("comment/list", data, { dispatch }), + info: + (data = {}) => + async (dispatch) => { + await proxy.get("comment/info", data, { dispatch }); + }, + add: + (data = {}, data2) => + async (dispatch) => { + await proxy.post("comment/add", data, { dispatch }); + if (data2) await proxy.get("book/info", data2, { dispatch }); + }, + del: + (data = {}, data2 = {}) => + async (dispatch) => { + await proxy.delete("ar/delete", data); + await proxy.get("ar/list", data2, { dispatch }); + }, + update: + (data = {}, data2 = {}) => + async (dispatch) => { + await proxy.put("ar/update", data); + await proxy.get("ar/list", data2, { dispatch }); + }, +}; + +export default comment; \ No newline at end of file diff --git a/src/redux/actions/form.js b/src/redux/actions/form.js new file mode 100644 index 0000000..252c06b --- /dev/null +++ b/src/redux/actions/form.js @@ -0,0 +1,8 @@ +const form = { + setTicket: + (data = {}) => + async (dispatch) => + await dispatch({ type: "form/ticket", data }), +}; + +export default form; \ No newline at end of file diff --git a/src/redux/actions/index.js b/src/redux/actions/index.js index d354661..1ebf7bb 100644 --- a/src/redux/actions/index.js +++ b/src/redux/actions/index.js @@ -12,4 +12,6 @@ export { default as file } from "./file"; export { default as qr } from "./qr"; export {default as userAddress} from "./userAddress"; export { default as transport } from "./transport"; -export { default as activation } from "./activation"; \ No newline at end of file +export { default as activation } from "./activation"; +export { default as form } from "./form"; +export { default as comment } from "./comment"; \ No newline at end of file diff --git a/src/redux/actions/userProduct.js b/src/redux/actions/userProduct.js index 2436d7f..e30e9d8 100644 --- a/src/redux/actions/userProduct.js +++ b/src/redux/actions/userProduct.js @@ -28,6 +28,11 @@ const userProduct = { await proxy.delete("userProduct/delete", data); await proxy.get("userProduct/list", data2, { dispatch }); }, + myList: + (data = {}) => + async (dispatch) => { + await proxy.get("userProduct/myList", data, { dispatch }); + }, }; export default userProduct; diff --git a/src/redux/reducers/comment.js b/src/redux/reducers/comment.js new file mode 100644 index 0000000..aefaaed --- /dev/null +++ b/src/redux/reducers/comment.js @@ -0,0 +1,34 @@ +const initialState = { + loading: false, + error: null, + list: null, +}; + +export default function comment(state = initialState, action) { + let { type, data } = action; + switch (type) { + case "comment/list": + return { ...state, loading: false, error: null }; + case "comment/update": + return { ...state, loading: false, error: null }; + case "comment/add": + toast.success("ثبت درخواست با موفقیت انجام شد"); + return { ...state, loading: false, error: null }; + case "comment/delete": + return { ...state, loading: false, error: null }; + case "comment/info": + return { + ...state, + loading: false, + list: data, + error: null, + }; + case "comment/loading": + return { ...state, loading: true }; + case "comment/error": + toast.error(data.message); + return { ...state, loading: false, error: data.message }; + default: + return state; + } +} \ No newline at end of file diff --git a/src/redux/reducers/form.js b/src/redux/reducers/form.js new file mode 100644 index 0000000..796afbf --- /dev/null +++ b/src/redux/reducers/form.js @@ -0,0 +1,24 @@ +const initialState = { + loading: false, + error: null, + ticket: {}, +}; + +export default function form(state = initialState, action) { + let { type, data } = action; + switch (type) { + case "form/ticket": + return { + ...state, + loading: false, + ticket: { ...state.ticket, [data.name]: data.value }, + error: null, + }; + case "form/loading": + return { ...state, loading: true }; + case "form/error": + return { ...state, loading: false, error: data.message }; + default: + return state; + } +} \ No newline at end of file diff --git a/src/redux/reducers/index.js b/src/redux/reducers/index.js index d2642b8..53bd961 100644 --- a/src/redux/reducers/index.js +++ b/src/redux/reducers/index.js @@ -11,4 +11,6 @@ export { default as userProduct } from "./userProduct"; import { default as qr } from "./qr"; export { default as userAddress } from "./userAddress"; export { default as transport } from "./transport"; -export { default as activation } from "./activation"; \ No newline at end of file +export { default as activation } from "./activation"; +export { default as form } from "./form"; +export { default as comment } from "./comment"; \ No newline at end of file diff --git a/src/redux/reducers/userProduct.js b/src/redux/reducers/userProduct.js index 4dab0bf..6a35dc1 100644 --- a/src/redux/reducers/userProduct.js +++ b/src/redux/reducers/userProduct.js @@ -4,6 +4,7 @@ const initialState = { loading: false, error: null, list: [], + myList: [], info: null, sum: null, checkEmpty: false, @@ -12,6 +13,8 @@ const initialState = { export default function userFactor(state = initialState, action) { let { type, data } = action; switch (type) { + case "userProduct/myList": + return { ...state, loading: false, myList: data, error: null }; case "userProduct/list": const checkEmpty = data.filter( (item) => item.condition === 2 && item.product.productType === (1 || 3) diff --git a/src/redux/store.js b/src/redux/store.js index 784822f..b1b2138 100644 --- a/src/redux/store.js +++ b/src/redux/store.js @@ -16,6 +16,8 @@ import userProduct from "./reducers/userProduct"; import qr from './reducers/qr'; import userAddress from "./reducers/userAddress"; import transport from "./reducers/transport" +import comment from './reducers/comment'; +import form from "./reducers/form"; const persistConfig = { key: "root", @@ -49,6 +51,8 @@ const store = createStore( qr, userAddress, transport, + comment, + form }) ), initialState, diff --git a/src/screens/Contact/Box.js b/src/screens/Contact/Box.js index fff2170..01b856b 100644 --- a/src/screens/Contact/Box.js +++ b/src/screens/Contact/Box.js @@ -1,71 +1,103 @@ -import { View, Text, Image, TouchableOpacity, Platform } from "react-native"; +import { View, Text, Image, TouchableOpacity, Platform, Dimensions } from "react-native"; +import RBSheet from "react-native-raw-bottom-sheet"; import React from "react"; import { connect } from "react-redux"; +//components +import Ticket from '../../components/BottomSheetComponents/Ticket'; + //style import tw from "tailwind-rn"; import fontSize from "../../constants/fontSize"; const ios = Platform.OS === "ios"; +const {height, width} = Dimensions.get("window"); const Box = ({ info, mobile }) => { + const refRBSheet = React.useRef(); + return ( - - - - - {info.title.text} - - + refRBSheet.current.open()} + > + + + - {info.description.text} - - - {info?.link?.title} - - - + }} + > + {info.title.text} + + + {info.description.text} + + + {info?.link?.title} + + + + + + + ); }; diff --git a/src/screens/Contact/index.js b/src/screens/Contact/index.js index 6daad6e..15ddfc9 100644 --- a/src/screens/Contact/index.js +++ b/src/screens/Contact/index.js @@ -78,7 +78,7 @@ Contact.defaultProps = { link: "/support", color: "#766600", }, - bg: "#D3B70222", + bg: "#D3B70233", borderColor: "#D3B70255", }, call: { @@ -89,7 +89,7 @@ Contact.defaultProps = { color: "#025816", }, link: null, - bg: "#69FF5F22", + bg: "#69FF5F33", borderColor: "#69FF5F55", }, address: { @@ -104,7 +104,7 @@ Contact.defaultProps = { link: "/sell", color: "#0A7769", }, - bg: "#0A776922", + bg: "#0A776933", borderColor: "#0A776955", }, },