reza added something

master
Reza_ashrafi 3 years ago
parent d50999c353
commit c3e66ec473
  1. 160
      src/components/BottomSheetComponents/Ticket.js
  2. 2
      src/components/CustomTextInput.js
  3. 32
      src/redux/actions/comment.js
  4. 8
      src/redux/actions/form.js
  5. 2
      src/redux/actions/index.js
  6. 5
      src/redux/actions/userProduct.js
  7. 34
      src/redux/reducers/comment.js
  8. 24
      src/redux/reducers/form.js
  9. 2
      src/redux/reducers/index.js
  10. 3
      src/redux/reducers/userProduct.js
  11. 4
      src/redux/store.js
  12. 144
      src/screens/Contact/Box.js
  13. 6
      src/screens/Contact/index.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 (
<View style={tw('flex-1 pb-4 px-4')}>
<ScrollView style={tw("flex flex-1")}>
{!status && (
<>
<CustomTextInput
label="نام و نام خانوادگی"
name="name"
onChange={(name, value) => setTicket({ name, value })}
value={ticket?.name || ""}
regex={(val) => val}
/>
<CustomTextInput
label="شماره تماس"
name="cellphone"
onChange={(name, value) => setTicket({ name, value })}
value={ticket?.cellphone || ""}
regex={(val) => onInput.phonenumber(val)}
maxLength="11"
/>
</>
)}
<Select
defaultValue={ticket?.unit || myProductList[0]}
options={status && myProductList?.length ? opt : opt.slice(0, 3)}
name="unit"
onChange={(name, value) => setTicket({ name, value })}
width={"100%"}
/>
{ticket?.unit === "واحد محتوایی" && (
<Select
name="bookId"
defaultValue={ticket?.subject}
options={[
...new Set(
myProductList?.map((item) => [
item?.product?.book?.id,
`${item?.product?.book.name} پایه ${
Object.values(grades)[item.product.book.gradeId]
}`,
]) || []
),
]}
onChange={(name, value) => setTicket({ name, value })}
width={"100%"}
/>
)}
<CustomTextInput
name="subject"
onChange={(name, value) => setTicket({ name, value })}
value={ticket?.subject || ""}
regex={(val) => val}
label="موضوع"
/>
<CustomTextInput
name="text"
onChange={(name, value) => setTicket({ name, value })}
value={ticket?.text || ""}
regex={(val) => val}
label="متن پیام"
multiline={true}
/>
<View style={tw("mt-4")}></View>
</ScrollView>
<CustomPressable
title={"ارسال پیام"}
backgroundColor={Colors.theme1[colorScheme].greenCF}
color={"white"}
border={{ color: "#196EC0", width: 0 }}
width={"100%"}
onPress={() => send()}
/>
</View>
);
};
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);

@ -31,6 +31,7 @@ const FloatingLabelInput = ({
regex, regex,
mobile, mobile,
keyboardType, keyboardType,
multiline,
...props ...props
}) => { }) => {
const colorScheme = useColorScheme(); const colorScheme = useColorScheme();
@ -96,6 +97,7 @@ const FloatingLabelInput = ({
value={value} value={value}
onBlur={() => (value ? {} : setIsFocused(() => false))} onBlur={() => (value ? {} : setIsFocused(() => false))}
keyboardType={keyboardType} keyboardType={keyboardType}
multiline={multiline}
/> />
</View> </View>
); );

@ -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;

@ -0,0 +1,8 @@
const form = {
setTicket:
(data = {}) =>
async (dispatch) =>
await dispatch({ type: "form/ticket", data }),
};
export default form;

@ -13,3 +13,5 @@ export { default as qr } from "./qr";
export {default as userAddress} from "./userAddress"; export {default as userAddress} from "./userAddress";
export { default as transport } from "./transport"; export { default as transport } from "./transport";
export { default as activation } from "./activation"; export { default as activation } from "./activation";
export { default as form } from "./form";
export { default as comment } from "./comment";

@ -28,6 +28,11 @@ const userProduct = {
await proxy.delete("userProduct/delete", data); await proxy.delete("userProduct/delete", data);
await proxy.get("userProduct/list", data2, { dispatch }); await proxy.get("userProduct/list", data2, { dispatch });
}, },
myList:
(data = {}) =>
async (dispatch) => {
await proxy.get("userProduct/myList", data, { dispatch });
},
}; };
export default userProduct; export default userProduct;

@ -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;
}
}

@ -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;
}
}

@ -12,3 +12,5 @@ import { default as qr } from "./qr";
export { default as userAddress } from "./userAddress"; export { default as userAddress } from "./userAddress";
export { default as transport } from "./transport"; export { default as transport } from "./transport";
export { default as activation } from "./activation"; export { default as activation } from "./activation";
export { default as form } from "./form";
export { default as comment } from "./comment";

@ -4,6 +4,7 @@ const initialState = {
loading: false, loading: false,
error: null, error: null,
list: [], list: [],
myList: [],
info: null, info: null,
sum: null, sum: null,
checkEmpty: false, checkEmpty: false,
@ -12,6 +13,8 @@ const initialState = {
export default function userFactor(state = initialState, action) { export default function userFactor(state = initialState, action) {
let { type, data } = action; let { type, data } = action;
switch (type) { switch (type) {
case "userProduct/myList":
return { ...state, loading: false, myList: data, error: null };
case "userProduct/list": case "userProduct/list":
const checkEmpty = data.filter( const checkEmpty = data.filter(
(item) => item.condition === 2 && item.product.productType === (1 || 3) (item) => item.condition === 2 && item.product.productType === (1 || 3)

@ -16,6 +16,8 @@ import userProduct from "./reducers/userProduct";
import qr from './reducers/qr'; import qr from './reducers/qr';
import userAddress from "./reducers/userAddress"; import userAddress from "./reducers/userAddress";
import transport from "./reducers/transport" import transport from "./reducers/transport"
import comment from './reducers/comment';
import form from "./reducers/form";
const persistConfig = { const persistConfig = {
key: "root", key: "root",
@ -49,6 +51,8 @@ const store = createStore(
qr, qr,
userAddress, userAddress,
transport, transport,
comment,
form
}) })
), ),
initialState, initialState,

@ -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 React from "react";
import { connect } from "react-redux"; import { connect } from "react-redux";
//components
import Ticket from '../../components/BottomSheetComponents/Ticket';
//style //style
import tw from "tailwind-rn"; import tw from "tailwind-rn";
import fontSize from "../../constants/fontSize"; import fontSize from "../../constants/fontSize";
const ios = Platform.OS === "ios"; const ios = Platform.OS === "ios";
const {height, width} = Dimensions.get("window");
const Box = ({ info, mobile }) => { const Box = ({ info, mobile }) => {
const refRBSheet = React.useRef();
return ( return (
<TouchableOpacity <>
style={[ <TouchableOpacity
tw( style={[
`flex flex-row-reverse rounded-md mt-4 ${ tw(
mobile ? "py-4 px-3" : "py-5 px-5" `flex flex-row-reverse rounded-md mt-4 ${
}` mobile ? "py-3 px-3" : "py-5 px-5"
), }`
{ ),
backgroundColor: info.bg, {
borderColor: info.borderColor, backgroundColor: info.bg,
borderWidth: 1, borderColor: info.borderColor,
}, borderWidth: 1,
]} },
> ]}
<Image onPress={() => refRBSheet.current.open()}
source={info.icon} >
style={{ width: mobile ? 40 : 55, height: mobile ? 40 : 55 }} <Image
/> source={info.icon}
<View style={tw("flex flex-1 mr-3")}> style={{ width: mobile ? 40 : 55, height: mobile ? 40 : 55 }}
<Text />
style={{ <View style={tw("flex flex-1 mr-3")}>
fontFamily: "bold", <Text
fontSize: mobile ? fontSize.lg : fontSize.xl3, style={{
color: info.title.color, fontFamily: "bold",
textAlign: ios ? "right" : "auto", fontSize: mobile ? fontSize.lg : fontSize.xl3,
}} color: info.title.color,
>
{info.title.text}
</Text>
<Text
style={[
tw("mt-1"),
{
fontFamily: "light",
fontSize: mobile ? fontSize.sm : fontSize.lg,
color: info.description.color,
textAlign: ios ? "right" : "auto", textAlign: ios ? "right" : "auto",
}, }}
]} >
> {info.title.text}
{info.description.text} </Text>
</Text> <Text
<Text style={[
style={[ tw("mt-1"),
tw("self-start mt-2.5"), {
{ fontFamily: "light",
fontFamily: "demi", fontSize: mobile ? fontSize.sm : fontSize.lg,
fontSize: mobile ? fontSize.sm : fontSize.lg, color: info.description.color,
color: info?.link?.color, textAlign: ios ? "right" : "auto",
}, },
]} ]}
> >
{info?.link?.title} {info.description.text}
</Text> </Text>
</View> <Text
</TouchableOpacity> style={[
tw("self-start mt-2.5"),
{
fontFamily: "demi",
fontSize: mobile ? fontSize.sm : fontSize.lg,
color: info?.link?.color,
},
]}
>
{info?.link?.title}
</Text>
</View>
</TouchableOpacity>
<RBSheet
ref={refRBSheet}
closeOnDragDown={true}
dragFromTopOnly={true}
closeOnPressMask={true}
height={height / 4 * 3}
customStyles={{
wrapper: {
backgroundColor: "#00000077",
},
container: {
padding: 0,
borderTopLeftRadius: 30,
borderTopRightRadius: 30,
},
draggableIcon: {
backgroundColor: "#000",
},
}}
>
<Ticket />
</RBSheet>
</>
); );
}; };

@ -78,7 +78,7 @@ Contact.defaultProps = {
link: "/support", link: "/support",
color: "#766600", color: "#766600",
}, },
bg: "#D3B70222", bg: "#D3B70233",
borderColor: "#D3B70255", borderColor: "#D3B70255",
}, },
call: { call: {
@ -89,7 +89,7 @@ Contact.defaultProps = {
color: "#025816", color: "#025816",
}, },
link: null, link: null,
bg: "#69FF5F22", bg: "#69FF5F33",
borderColor: "#69FF5F55", borderColor: "#69FF5F55",
}, },
address: { address: {
@ -104,7 +104,7 @@ Contact.defaultProps = {
link: "/sell", link: "/sell",
color: "#0A7769", color: "#0A7769",
}, },
bg: "#0A776922", bg: "#0A776933",
borderColor: "#0A776955", borderColor: "#0A776955",
}, },
}, },

Loading…
Cancel
Save