index.jsx 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. import styles from './styles.module.scss';
  2. import {useDispatch, useSelector} from "react-redux";
  3. import {ReactComponent as EmptyAvatar} from '@assets/avatar_empty.svg';
  4. import {getIsGuest, getLogoutStatus, getUpgradeBonus, getUserInfo, isLogined} from "@features/mainSlice";
  5. import Spring from "@components/Spring";
  6. import {useNavigate} from "react-router-dom";
  7. import {ROUTE_PATH} from "@constants/routes";
  8. import LazyImage from "@components/LazyImage";
  9. import USD from "@assets/lvicon/USD.black.png";
  10. import {formatCash, numFormatter, stringFormat} from "@utils/helpers";
  11. import SvgIcon from "@components/SvgIcon";
  12. import {ReactComponent as Male} from '@assets/singlesvg/gener/male.svg';
  13. import {ReactComponent as FeMale} from '@assets/singlesvg/gener/female.svg';
  14. import {ReactComponent as GenderIcon} from '@assets/singlesvg/gener/gender.svg';
  15. import {ReactComponent as MobileIcon} from '@assets/singlesvg/mobile.svg';
  16. import {ReactComponent as EmailIcon} from '@assets/singlesvg/email.svg';
  17. import {ReactComponent as InstallIcon} from "@assets/singlesvg/install.svg";
  18. import {ReactComponent as SoundOnIcon} from "@assets/singlesvg/sound-on.svg";
  19. import {ReactComponent as SoundOffIcon} from "@assets/singlesvg/sound-off.svg";
  20. import {ReactComponent as BindPhone} from "@assets/singlesvg/userupgrade.svg";
  21. import {CopyToClipboard} from 'react-copy-to-clipboard';
  22. import {toast} from "react-toastify";
  23. import ToggleButtonGroup from "@mui/material/ToggleButtonGroup";
  24. import {StyledThemeTabs} from "@layout/Sidebar/styles";
  25. import {useThemeProvider} from "@contexts/themeContext";
  26. import ToggleButton from "@mui/material/ToggleButton";
  27. import {reqChangeInfo, reqLogout} from "@features/api";
  28. import {REQ_STATUS} from "@api/config";
  29. import SmallLoading from "@components/SmallLoading";
  30. import {APP_GENDER, APP_THEME} from "@constants/app";
  31. import AntSwitch from "@components/AntSwitch";
  32. import LazyImgix from "@components/Imgix/LazyImgix";
  33. const i18n=global.i18n;
  34. const UserSettings=()=>{
  35. const isLogin=useSelector(isLogined);
  36. const user=useSelector(getUserInfo);
  37. const logoutStatus=useSelector(getLogoutStatus);
  38. const dispatch = useDispatch();
  39. const navigate=useNavigate();
  40. const {theme, toggleTheme,setIsShowLang,installOpen,toggleInstallOpen,soundOpen,toggleSoundOpen} = useThemeProvider();
  41. const guest=useSelector(getIsGuest);
  42. const upgradBonus=useSelector(getUpgradeBonus);
  43. const renderEmpty=()=>{
  44. return (
  45. <div className={styles.wrap_item}>
  46. <div className={styles.user_info}>
  47. <EmptyAvatar className={styles.avatar_empty}/>
  48. <div className={styles.empty_info}>
  49. <span className={styles.welcome}>
  50. {i18n.t("settings.user_info.welcome")}
  51. </span>
  52. <span className={styles.login_tips}>
  53. {i18n.t("settings.user_info.tips")}
  54. </span>
  55. </div>
  56. </div>
  57. <div className={styles.login_con}>
  58. <button className={`button-gray ${styles.button}`} onClick={()=>{
  59. navigate(ROUTE_PATH.SIGN_IN);
  60. }}>
  61. {i18n.t("sign_in")}
  62. </button>
  63. <button className={`button-green ${styles.button}`} onClick={()=>{
  64. navigate(ROUTE_PATH.SIGN_UP);
  65. }}>
  66. {i18n.t("sign_up")}
  67. </button>
  68. </div>
  69. </div>
  70. )
  71. }
  72. const getPhone=()=>{
  73. let loc=user.RegisterLocation;
  74. let phone=user.Phone;
  75. if (phone.startsWith(loc)){
  76. phone=phone.replace(loc,"");
  77. }
  78. return phone;
  79. }
  80. const getEmail=()=>{
  81. let email=user.Email;
  82. if (email==null||email==""){
  83. return "--";
  84. }
  85. return email;
  86. }
  87. const renderPhone=()=>{
  88. return (
  89. <div className={styles.action_item}>
  90. <div className={styles.action_left}>
  91. <MobileIcon className={styles.icon}></MobileIcon>
  92. <div>{i18n.t("settings.phone")}</div>
  93. </div>
  94. <div className={styles.action_right}>
  95. <div>{"+"+user.RegisterLocation}</div>
  96. <div>{getPhone()}</div>
  97. </div>
  98. </div>
  99. )
  100. }
  101. const renderEmail=()=>{
  102. return (
  103. <div className={styles.action_item}>
  104. <div className={styles.action_left}>
  105. <EmailIcon className={styles.icon}></EmailIcon>
  106. <div>{i18n.t("settings.email")}</div>
  107. </div>
  108. <div className={styles.action_right}>
  109. <div>{getEmail()}</div>
  110. </div>
  111. </div>
  112. )
  113. }
  114. const renderUser=()=>{
  115. let gender=(<></>);
  116. if (user.Gender===APP_GENDER.FEMALE){
  117. gender=(<FeMale className={styles.female}/>);
  118. }
  119. else if (user.Gender===APP_GENDER.MALE){
  120. gender=(<Male className={styles.male}/>);
  121. }
  122. return (
  123. <div className={styles.wrap_item}>
  124. <div className={styles.user_con}>
  125. <div className={styles.user_info}>
  126. {/*<LazyImage wrapperClassName={styles.avatar} src={user.img} alt={"avatar"}></LazyImage>*/}
  127. <LazyImgix className={styles.avatar} src={user.img} alt={"avatar"} width={100}></LazyImgix>
  128. <div className={`${styles.user_info} ${styles.info}`}>
  129. <div className={styles.info_item}>
  130. <div className={styles.name}>{user.NickName}</div>
  131. {gender}
  132. </div>
  133. <CopyToClipboard text={user.GameID} onCopy={()=>{
  134. toast.success(i18n.t("copy_success"));
  135. }}>
  136. <div className={styles.info_item}>
  137. <div className={styles.text}>{i18n.t("settings.user_info.id")}</div>
  138. <div className={styles.text}>{user.GameID}</div>
  139. <button>
  140. <SvgIcon className={styles.icon_copy} herf={"icon_Copy"}/>
  141. </button>
  142. </div>
  143. </CopyToClipboard>
  144. <div className={styles.info_item}>
  145. <img className={styles.icon_golds} src={USD}/>
  146. <div className={styles.golds}>{global.DOLLAR+""+numFormatter(user.Score)}</div>
  147. </div>
  148. </div>
  149. </div>
  150. <div className={styles.user_edit_con}>
  151. <button className={styles.edit_btn} onClick={()=>{
  152. navigate(ROUTE_PATH.EDIT_PROFILE);
  153. }}>
  154. <SvgIcon className={styles.icon} herf={"icon_Edit"}/>
  155. </button>
  156. </div>
  157. </div>
  158. {/*<div className={styles.card_line}></div>*/}
  159. {/*{renderPhone()}*/}
  160. {/*{renderEmail()}*/}
  161. </div>
  162. )
  163. }
  164. const renderUserInfo=()=>{
  165. return (
  166. <>
  167. {
  168. isLogin?renderUser():renderEmpty()
  169. }
  170. </>
  171. )
  172. }
  173. const renderItemSecurity=()=>{
  174. return (
  175. <>
  176. {
  177. isLogin?(
  178. <button className={styles.action_item} onClick={()=>{
  179. // navigate(ROUTE_PATH.EDIT_PWD);
  180. navigate(ROUTE_PATH.SECURITY);
  181. }}>
  182. <div className={styles.action_left}>
  183. <SvgIcon className={styles.icon} herf={"icon_Locked"}></SvgIcon>
  184. <div>{i18n.t("settings.security")}</div>
  185. </div>
  186. <div className={styles.action_right}>
  187. <SvgIcon className={styles.icon} herf={"icon_Arrow"}></SvgIcon>
  188. </div>
  189. </button>
  190. ):(<></>)
  191. }
  192. </>
  193. )
  194. }
  195. const renderItemLang=()=>{
  196. return (
  197. <button className={styles.action_item} onClick={()=>{
  198. setIsShowLang(true);
  199. }}>
  200. <div className={styles.action_left}>
  201. <SvgIcon className={styles.icon} herf={"icon_Language"}></SvgIcon>
  202. <div>{i18n.t("settings.language")}</div>
  203. </div>
  204. <div className={styles.action_right}>
  205. <div>{i18n.getCurrLangName()}</div>
  206. <SvgIcon className={styles.icon} herf={"icon_Arrow"}></SvgIcon>
  207. </div>
  208. </button>
  209. )
  210. }
  211. const handleTheme=(theme)=>{
  212. toggleTheme();
  213. // "DefaultLanguage": "en",
  214. // "ThemeColor": "dark"
  215. if (!isLogin)return;
  216. dispatch(reqChangeInfo({
  217. ThemeColor:theme
  218. }));
  219. }
  220. const renderItemTheme=()=>{
  221. return (
  222. <button className={styles.action_item}>
  223. <div className={styles.action_left}>
  224. <SvgIcon className={styles.icon} herf={"icon_Exchange"}></SvgIcon>
  225. <div>{i18n.t("settings.theme")}</div>
  226. </div>
  227. <div className={styles.action_right}>
  228. <div className={styles.theme_con}>
  229. <ToggleButtonGroup sx={{
  230. display:"flex",
  231. position: "relative",
  232. width:"100%",
  233. height:"100%",
  234. alignItems:"center",
  235. justifyContent:"space-between"
  236. }} exclusive value={theme} onChange={(event, value)=>{
  237. handleTheme(value);
  238. }}>
  239. <div className={styles.theme_bg} style={{left: `${theme === APP_THEME.DARK ? '0%' : '50%'}`}}/>
  240. <ToggleButton sx={{
  241. display:"flex",
  242. position: "relative",
  243. width:"100%",
  244. height:"100%",
  245. alignItems:"center",
  246. justifyContent:"center",
  247. border:"none",
  248. backgroundColor:'transparent !important;',
  249. ".Mui-selected:hover":{
  250. backgroundColor: 'transparent !important;',
  251. }
  252. }} value={APP_THEME.DARK}>
  253. <SvgIcon className={`${styles.theme_icon} ${theme===APP_THEME.DARK?styles.active:''}`} herf={"icon_Dark"}/>
  254. </ToggleButton>
  255. <ToggleButton sx={{
  256. display:"flex",
  257. position: "relative",
  258. width:"100%",
  259. height:"100%",
  260. alignItems:"center",
  261. justifyContent:"center",
  262. border:"none",
  263. backgroundColor:'transparent !important;',
  264. ".Mui-selected:hover":{
  265. backgroundColor: 'transparent !important;',
  266. }
  267. }} value={"light"}>
  268. <SvgIcon className={`${styles.theme_icon} ${theme===APP_THEME.LIGHT?styles.active:''}`} herf={"icon_Light"}/>
  269. </ToggleButton>
  270. </ToggleButtonGroup>
  271. </div>
  272. </div>
  273. </button>
  274. )
  275. }
  276. const renderItemGender=()=>{
  277. return (
  278. <div className={styles.action_item}>
  279. <div className={styles.action_left}>
  280. <GenderIcon className={styles.icon}></GenderIcon>
  281. <div>{i18n.t("settings.gender")}</div>
  282. </div>
  283. <div className={styles.action_right}>
  284. {
  285. user.Gender===APP_GENDER.FEMALE?(<FeMale className={styles.gender}></FeMale>):(<Male className={styles.gender}></Male>)
  286. }
  287. <SvgIcon className={styles.icon} herf={"icon_Arrow"}></SvgIcon>
  288. </div>
  289. </div>
  290. )
  291. }
  292. const renderItemInstallBanner=()=>{
  293. return (
  294. <div className={styles.action_item}>
  295. <div className={styles.action_left}>
  296. <InstallIcon className={styles.icon}></InstallIcon>
  297. <div>{i18n.t("settings.install_banner")}</div>
  298. </div>
  299. <div className={styles.action_right}>
  300. <AntSwitch checked={installOpen} onChange={()=>{
  301. toggleInstallOpen();
  302. }}></AntSwitch>
  303. </div>
  304. </div>
  305. )
  306. }
  307. const renderItemSound=()=>{
  308. return (
  309. <div className={styles.action_item}>
  310. <div className={styles.action_left}>
  311. {
  312. soundOpen?(<SoundOnIcon className={styles.icon}></SoundOnIcon>):(<SoundOffIcon className={styles.icon}></SoundOffIcon>)
  313. }
  314. <div>{i18n.t("settings.sound")}</div>
  315. </div>
  316. <div className={styles.action_right}>
  317. <AntSwitch checked={soundOpen} onChange={()=>{
  318. toggleSoundOpen();
  319. }}></AntSwitch>
  320. </div>
  321. </div>
  322. )
  323. }
  324. const renderBindPhone=()=>{
  325. let isShowBind=false;
  326. if (guest===1){
  327. if (user!=null){
  328. if (user.Phone==null||user.Phone===""){
  329. isShowBind=true;
  330. }
  331. }
  332. }
  333. let bonusStr=stringFormat(i18n.t("settings.bonus"),[global.DOLLAR+""+formatCash(upgradBonus,0)]);
  334. return (
  335. <>
  336. {
  337. isLogin&&isShowBind?(
  338. <button className={styles.action_item} onClick={()=>{
  339. global.showBindPhone();
  340. }}>
  341. <div className={styles.action_left}>
  342. <BindPhone className={styles.icon}></BindPhone>
  343. <div>{i18n.t("settings.bindPhone")}</div>
  344. </div>
  345. <div className={styles.action_right}>
  346. {
  347. upgradBonus>0?(
  348. <div className={styles.bonus_con}>
  349. {bonusStr}
  350. </div>
  351. ):(<></>)
  352. }
  353. <SvgIcon className={styles.icon} herf={"icon_Arrow"}></SvgIcon>
  354. </div>
  355. </button>
  356. ):(<></>)
  357. }
  358. </>
  359. )
  360. }
  361. const renderSetting=()=>{
  362. return (
  363. <div className={`${styles.wrap_item} ${styles.action_wrap}`}>
  364. {renderItemSecurity()}
  365. {renderBindPhone()}
  366. {renderItemInstallBanner()}
  367. {renderItemSound()}
  368. {renderItemLang()}
  369. {/*{renderItemGender()}*/}
  370. {renderItemTheme()}
  371. </div>
  372. )
  373. }
  374. const renderLogout=()=>{
  375. return (
  376. <>
  377. {
  378. isLogin?(
  379. <button className={`button-gray ${styles.logout}`} onClick={()=>{
  380. if (logoutStatus===REQ_STATUS.LOADING)return;
  381. dispatch(reqLogout());
  382. }}>
  383. {
  384. logoutStatus===REQ_STATUS.LOADING?(<SmallLoading fill={"#fff"} />):(<>{i18n.t("links.log_out")}</>)
  385. }
  386. </button>
  387. ):(<></>)
  388. }
  389. </>
  390. )
  391. }
  392. return (
  393. <div className={styles.container}>
  394. <Spring type="slideUp" className={styles.content}>
  395. {renderUserInfo()}
  396. {renderSetting()}
  397. {renderLogout()}
  398. </Spring>
  399. </div>
  400. )
  401. }
  402. export default UserSettings;