fix: apply language support in profile also and save in database, issue of text translate in guest login flow and other place

This commit is contained in:
RaktimaNXG
2024-08-06 17:02:16 +05:30
parent 10083ac807
commit 4c7d771bb3
19 changed files with 320 additions and 202 deletions
@@ -38,6 +38,7 @@
"upgrade-to":"Upgrade to",
"plan":"Plan",
"subscribe-card-plan":"Sign 100 docs using API. Only $0.15/doc after that.",
"user-name-limit-char":"To have a username less than 8 character please subscribe",
"tour-content":"Don't show this again",
"pro":"PRO",
"team":"TEAM",
@@ -181,6 +182,13 @@
"next":"Next",
"select-folder":"Select Folder",
"OpenSign-drive":"OpenSign™ Drive",
"drive-document-status":{
"Completed":"Completed",
"Declined":"Declined",
"Draft":"Draft",
"Expired":"Expired",
"In Progress":"In Progress"
},
"select-folder-help" :"If you do not select a folder, your signed document will be saved in the Main OpenSign drive folder.",
"no-data":"No data found",
"save-here":"Save Here",
@@ -296,6 +304,7 @@
"enter-otp":"Enter OTP",
"verify":"Verify",
"resend":"Resend",
"verify-email":"Please verify your email !",
"send-otp":" Send OTP",
"otp-placeholder":"Enter OTP received over email",
@@ -332,9 +341,17 @@
"email-mssg":" Recipients added here will get a copy of the signed document.",
"email-error-1":" please provide correct email address",
"email-error-2" :"You can only send to ten recipients at a time.",
"Email-verified-alert-1":"Email is verified.",
"Email-verified-alert-2" :"Email is already verified.",
"upload-stamp-image":"Upload stamp image",
"draw":"Draw",
"type":"Type",
"color-type":{
"red":"red",
"blue":"blue",
"black":"black",
"yellow":"yellow"
},
"my-initials":"My Initials",
"upload":"Upload",
"initial-teb":"Initials",
@@ -516,6 +533,10 @@
"generated-on":"Generated On",
"text-field":"Text field",
"font-size":"Font size",
"widget-status":{
"Required":"Required",
"Optional":"Optional"
},
"all-right":"All Rights Reserved",
"version":"version",
"social-media":{
@@ -39,6 +39,7 @@
"pro":"PRO",
"plan":"Plan",
"subscribe-card-plan":"Signez 100 documents à l'aide de l'API. Seulement 0,15 $/doc par la suite.",
"user-name-limit-char" :"Pour avoir un nom d'utilisateur de moins de 8 caractères s'il vous plaît s'abonner",
"tour-content":"Ne montre plus ça",
"team":"ÉQUIPE",
"docs":"Documents",
@@ -179,6 +180,13 @@
"next":"Suivant",
"select-folder" :"Sélectionner le dossier",
"OpenSign-drive":"Lecteur OpenSign™",
"drive-document-status":{
"Completed":"Complété",
"Declined":"Diminué",
"Draft":"Brouillon",
"Expired":"Expiré",
"In Progress":"En cours"
},
"select-folder-help" :"Si vous ne sélectionnez pas de dossier, votre document signé sera enregistré dans le dossier du lecteur principal OpenSign.",
"no-data" :"Aucune donnée disponible",
"save-here":"Enregistrer ici",
@@ -308,7 +316,7 @@
"date":"date",
"text":"texte",
"text input":"saisie de texte",
"checkbox":"checkbocase à cocher",
"checkbox":"case à cocher",
"dropdown":"dérouler",
"radio button":"bouton radio",
"image": "image",
@@ -330,9 +338,17 @@
"email-mssg" :"Les destinataires ajoutés ici recevront une copie du document signé.",
"email-error-1" :"veuillez fournir une adresse e-mail correcte",
"email-error-2" :"Vous ne pouvez envoyer qu'à dix destinataires à la fois.",
"Email-verified-alert-1" :"L'e-mail est vérifié.",
"Email-verified-alert-2" :"L'e-mail est déjà vérifié.",
"upload-stamp-image":"Télécharger l'image du tampon",
"draw":"Dessiner",
"type":"Type",
"type":"Taper",
"color-type":{
"red":"rouge",
"blue":"bleu",
"black":"noir",
"yellow":"jaune"
},
"my-initials" :"Mes initiales",
"upload" :"Télécharger",
"initial-teb":"Initiales",
@@ -455,7 +471,7 @@
"password-update-alert-2" :"Votre mot de passe actuel est manquant ou incorrect.",
"password-update-alert-3" :"Votre mot de passe actuel est manquant ou incorrect.",
"password-update-alert-4" :"Votre mot de passe et votre mot de passe de confirmation ne correspondent pas.",
"current-password":"Current Password",
"current-password":"mot de passe actuel",
"new-password" :"nouveau mot de passe",
"confirm-password":"Confirmez le mot de passe",
"file-alert-1":"La taille du fichier sélectionné est trop grande. Veuillez sélectionner un fichier inférieur à",
@@ -514,6 +530,10 @@
"generated-on" :"Généré le",
"text-field" :"Champ de texte",
"font-size" :"Taille de police",
"widget-status":{
"Required":"Requis",
"Optional":"Facultative"
},
"all-right" :"Tous droits réservés",
"version" :"version",
"social-media":{
@@ -553,7 +573,7 @@
"template-placeholder-4":"Faites glisser l'espace réservé pour un rôle n'importe où sur le document. N'oubliez pas qu'il apparaîtra dans la même couleur que le nom du destinataire pour une référence facile.",
"template-placeholder-5":"Cliquer sur 'Suivant' stockera le modèle actuel. Après l'enregistrement, vous serez invité à créer un nouveau document à partir de ce modèle si vous le souhaitez.",
"webhook-1":"Mettez à niveau maintenant pour définir le webhook",
"Need your Signature":"En cliquant sur cette carte, vous accéderez à la liste des documents en attente de révision.",
"Need your Signature":"En cliquant sur cette carte, vous accéderez à la liste des documents en attente de révision.",
"Out for signatures":"En cliquant sur cette carte, vous accéderez à une liste de documents en attente de signature.",
"Recent signature requests": "Voici une liste de documents qui attendent votre signature.",
"Recently sent for signatures":"Il s'agit d'une liste de documents que vous avez envoyés à d'autres parties pour signature.",
@@ -350,7 +350,7 @@ function DriveBody(props) {
</td>
<td>{createddate}</td>
<td>Pdf</td>
<td>{status}</td>
<td>{t(`drive-document-status.${status}`)}</td>
<td>
<i
onClick={(e) => {
@@ -526,7 +526,9 @@ function DriveBody(props) {
<strong className="text-[13px]">
{t("report-heading.Status")}:{" "}
</strong>
<span className="text-[12px] font-medium"> {status}</span>
<span className="text-[12px] font-medium">
{t(`drive-document-status.${status}`)}
</span>
<br />
<strong className="text-[13px]">
{t("report-heading.created-date")}:{" "}
+2 -4
View File
@@ -19,10 +19,9 @@ function PrevNext({ pageNumber, allPages, changePage }) {
disabled={pageNumber <= 1}
onClick={previousPage}
>
<span className="block lg:hidden">
<span className="block">
<i className="fa-light fa-backward" aria-hidden="true"></i>
</span>
<span className="lg:block hidden 2xl:text-[30px]">{t("prev")}</span>
</button>
<span className="text-xs text-base-content font-medium mx-2 2xl:text-[30px]">
{pageNumber || (allPages ? 1 : "--")} {t("of")} {allPages || "--"}
@@ -32,10 +31,9 @@ function PrevNext({ pageNumber, allPages, changePage }) {
disabled={pageNumber >= allPages}
onClick={nextPage}
>
<span className="block lg:hidden">
<span className="block">
<i className="fa-light fa-forward" aria-hidden="true"></i>
</span>
<span className="lg:block hidden 2xl:text-[30px]">{t("next")}</span>
</button>
</div>
);
@@ -2,25 +2,34 @@ import i18next from "i18next";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
function SelectLanguage() {
function SelectLanguage(props) {
const { i18n } = useTranslation();
const languages = [
{ value: "en", text: "English" },
{ value: "fr", text: "Français" }
];
const [lang, setLang] = useState(i18next.language || "en");
// This function put query that helps to
// change the language
// This function put query that helps to change the language
const handleChangeLang = (e) => {
setLang(e.target.value);
i18n.changeLanguage(e.target.value);
props?.updateExtUser &&
props.updateExtUser({
language: e.target.value
});
};
return (
<div className={`flex justify-center items-center mt-3 pb-2 md:pb-0 `}>
<div
className={`${
!props.isProfile && " mt-3 pb-2 md:pb-0 "
} flex justify-center items-center `}
>
<select
value={lang}
onChange={handleChangeLang}
className="op-select op-select-bordered md:w-[15%] w-[50%] bg-white op-select-sm "
className={`${
!props.isProfile && " md:w-[15%] w-[50%]"
} op-select op-select-bordered bg-white op-select-sm`}
>
<option disabled selected>
select
@@ -47,7 +47,7 @@ function TextFontSetting(props) {
{fontColorArr.map((color, ind) => {
return (
<option value={color} key={ind}>
{color}
{t(`color-type.${color}`)}
</option>
);
})}
@@ -240,7 +240,9 @@ const WidgetNameModal = (props) => {
formdata.status.toLowerCase() === data.toLowerCase()
}
/>
<div className="text-[13px] font-medium">{data}</div>
<div className="text-[13px] font-medium">
{t(`widget-status.${data}`)}
</div>
</div>
);
})}
@@ -268,7 +270,7 @@ const WidgetNameModal = (props) => {
"email"
].includes(props.defaultdata?.type) && (
<div className="flex items-center mb-[0.75rem]">
<span>Font size:</span>
<span>{t("font-size")}:</span>
<select
className="ml-[7px] op-select op-select-bordered op-select-sm focus:outline-none hover:border-base-content text-xs"
value={
@@ -298,7 +300,7 @@ const WidgetNameModal = (props) => {
{fontColorArr.map((color, ind) => {
return (
<option value={color} key={ind}>
{color}
{t(`color-type.${color}`)}
</option>
);
})}
+2 -2
View File
@@ -11,9 +11,9 @@ i18n
fallbackLng: "en", // Fallback to English if no other language is detected
detection: {
// Order and from where user language should be detected
order: ["navigator", "htmlTag", "path", "subdomain"],
order: ["localStorage", "navigator", "htmlTag", "path", "subdomain"],
// Cache user language on
caches: ["localStorage", "cookie"]
caches: ["localStorage"]
},
debug: true,
interpolation: {
+7 -1
View File
@@ -17,7 +17,7 @@ import { showHeader } from "../redux/reducers/showHeader";
import { useTranslation } from "react-i18next";
const HomeLayout = () => {
const { t } = useTranslation();
const { t, i18n } = useTranslation();
const navigate = useNavigate();
const location = useLocation();
const dispatch = useDispatch();
@@ -34,6 +34,12 @@ const HomeLayout = () => {
const [, setCookie] = useCookies(["accesstoken", "main_Domain"]);
const tenantId = localStorage.getItem("TenantId");
useEffect(() => {
const language = localStorage.getItem("i18nextLng");
i18n.changeLanguage(language);
}, []);
useEffect(() => {
if (!tenantId) {
setIsUserValid(false);
+3 -3
View File
@@ -72,7 +72,7 @@ function ChangePassword() {
value={currentpassword}
onChange={(e) => setCurrentPassword(e.target.value)}
className="op-input op-input-bordered op-input-sm text-xs w-full"
placeholder="Current Password"
placeholder={t("current-password")}
required
/>
</div>
@@ -86,7 +86,7 @@ function ChangePassword() {
value={newpassword}
onChange={(e) => setnewpassword(e.target.value)}
className="op-input op-input-bordered op-input-sm text-xs w-full"
placeholder="New Password"
placeholder={t("new-password")}
required
/>
</div>
@@ -100,7 +100,7 @@ function ChangePassword() {
className="op-input op-input-bordered op-input-sm text-xs w-full"
value={confirmpassword}
onChange={(e) => setconfirmpassword(e.target.value)}
placeholder="Confirm Password"
placeholder={t("confirm-password")}
required
/>
</div>
+1 -1
View File
@@ -42,7 +42,7 @@ const Dashboard = () => {
.map((col) => {
return {
selector: `[data-tut=${col.widget.data.tourSection}]`,
content: t(`tour-mssg.${col.widget.data.label}`),
content: t(`tour-mssg.${col.widget.label}`),
position: "top"
// style: { backgroundColor: "#abd4d2" },
};
+134 -130
View File
@@ -8,6 +8,7 @@ import { appInfo } from "../constant/appinfo";
import Parse from "parse";
import Loader from "../primitives/Loader";
import { useTranslation } from "react-i18next";
import SelectLanguage from "../components/pdf/SelectLanguage";
function GuestLogin() {
const { t } = useTranslation();
@@ -181,153 +182,156 @@ function GuestLogin() {
setContact((prev) => ({ ...prev, [e.target.name]: e.target.value }));
};
return (
<div className="p-[2rem]">
{isLoading ? (
<div className="flex flex-col justify-center items-center h-[100vh]">
<Loader />
<span className="text-[13px] text-[gray]">{isLoading.message}</span>
</div>
) : (
<div className="m-1 md:m-2 p-[30px] text-base-content bg-base-100 op-card shadow-md">
<div className="md:w-[250px] md:h-[66px] inline-block overflow-hidden mt-2 mb-11">
{appLogo && (
<img src={appLogo} className="object-contain" alt="logo" />
)}
<div className="p-14">
<div>
{isLoading ? (
<div className="flex flex-col justify-center items-center h-[100vh]">
<Loader />
<span className="text-[13px] text-[gray]">{isLoading.message}</span>
</div>
{contactId ? (
<>
{!EnterOTP ? (
<div className="w-full md:w-[50%] text-base-content">
<h1 className="text-2xl md:text-[30px]">{t("welcome")}</h1>
<legend className="text-[12px] text-[#878787] mt-2 mb-1">
{t("guest-email-alert")}
</legend>
<div className="p-[20px] outline outline-1 outline-slate-300/50 my-2 op-card shadow-md">
) : (
<div className="m-1 md:m-2 p-[30px] text-base-content bg-base-100 op-card shadow-md">
<div className="md:w-[250px] md:h-[66px] inline-block overflow-hidden mt-2 mb-11">
{appLogo && (
<img src={appLogo} className="object-contain" alt="logo" />
)}
</div>
{contactId ? (
<>
{!EnterOTP ? (
<div className="w-full md:w-[50%] text-base-content">
<h1 className="text-2xl md:text-[30px]">{t("welcome")}</h1>
<legend className="text-[12px] text-[#878787] mt-2 mb-1">
{t("guest-email-alert")}
</legend>
<div className="p-[20px] outline outline-1 outline-slate-300/50 my-2 op-card shadow-md">
<input
type="email"
name="mobile"
value={email}
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full disabled:text-[#5c5c5c] text-xs"
disabled
/>
</div>
<div className="mt-3">
<button
className="op-btn op-btn-primary"
onClick={(e) => handleSendOTPBtn(e)}
disabled={loading}
>
{loading ? t("loading") : t("get-verification-code")}
</button>
</div>
</div>
) : (
<form
className="w-full md:w-[50%] text-base-content"
onSubmit={VerifyOTP}
>
<h1 className="text-2xl md:text-[30px]">{t("welcome")}</h1>
<legend className="text-[12px] text-[#878787] mt-2">
{t("get-verification-code-2")}
</legend>
<div className="p-[20px] pt-[15px] outline outline-1 outline-slate-300/50 op-card my-2 shadow-md">
<p className="text-sm">{t("enter-verification-code")}</p>
<input
type="number"
className="mt-2 op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
name="OTP"
value={OTP}
onChange={(e) => setOTP(e.target.value)}
/>
</div>
<div className="mt-2.5">
<button
className="op-btn op-btn-primary"
type="submit"
disabled={loading}
>
{loading ? t("loading") : t("verify")}
</button>
</div>
</form>
)}
</>
) : (
<div className="w-full md:w-[50%] text-base-content">
<h1 className="text-2xl md:text-[30px]">{t("welcome")}</h1>
<legend className="text-[12px] text-[#878787] mt-2">
{t("provide-your-details")}
</legend>
<form
className="p-[20px] pt-[15px] outline outline-1 outline-slate-300/50 my-2 op-card shadow-md"
onSubmit={handleUserData}
>
<div className="mb-2">
<label
htmlFor="name"
className="block text-xs text-gray-700 font-semibold"
>
{t("name")}
<span className="text-[red] text-[13px]"> *</span>
</label>
<input
type="text"
name="name"
value={contact.name}
onChange={handleInputChange}
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
disabled={loading}
required
/>
</div>
<div className="mb-2">
<label
htmlFor="email"
className="block text-xs text-gray-700 font-semibold"
>
{t("email")}
<span className="text-[red] text-[13px]"> *</span>
</label>
<input
type="email"
name="mobile"
value={email}
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full disabled:text-[#5c5c5c] text-xs"
name="email"
value={contact.email}
onChange={handleInputChange}
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
required
disabled
/>
</div>
<div className="mt-3">
<button
className="op-btn op-btn-primary"
onClick={(e) => handleSendOTPBtn(e)}
disabled={loading}
<div className="mt-2.5">
<label
htmlFor="phone"
className="block text-xs text-gray-700 font-semibold"
>
{loading ? t("loading") : t("get-verification-code")}
</button>
</div>
</div>
) : (
<form
className="w-full md:w-[50%] text-base-content"
onSubmit={VerifyOTP}
>
<h1 className="text-2xl md:text-[30px]">{t("welcome")}</h1>
<legend className="text-[12px] text-[#878787] mt-2">
{t("get-verification-code-2")}
</legend>
<div className="p-[20px] pt-[15px] outline outline-1 outline-slate-300/50 op-card my-2 shadow-md">
<p className="text-sm">{t("enter-verification-code")}</p>
{t("phone")}
</label>
<input
type="number"
className="mt-2 op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
name="OTP"
value={OTP}
onChange={(e) => setOTP(e.target.value)}
type="text"
name="phone"
value={contact.phone}
onChange={handleInputChange}
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
disabled={loading}
/>
</div>
<div className="mt-2.5">
<div className="mt-2 flex justify-start">
<button
className="op-btn op-btn-primary"
type="submit"
className="op-btn op-btn-primary"
disabled={loading}
>
{loading ? t("loading") : t("verify")}
{loading ? t("loading") : t("next")}
</button>
</div>
</form>
)}
</>
) : (
<div className="w-full md:w-[50%] text-base-content">
<h1 className="text-2xl md:text-[30px]">{t("welcome")}</h1>
<legend className="text-[12px] text-[#878787] mt-2">
{t("provide-your-details")}
</legend>
<form
className="p-[20px] pt-[15px] outline outline-1 outline-slate-300/50 my-2 op-card shadow-md"
onSubmit={handleUserData}
>
<div className="mb-2">
<label
htmlFor="name"
className="block text-xs text-gray-700 font-semibold"
>
{t("name")}
<span className="text-[red] text-[13px]"> *</span>
</label>
<input
type="text"
name="name"
value={contact.name}
onChange={handleInputChange}
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
disabled={loading}
required
/>
</div>
<div className="mb-2">
<label
htmlFor="email"
className="block text-xs text-gray-700 font-semibold"
>
{t("email")}
<span className="text-[red] text-[13px]"> *</span>
</label>
<input
type="email"
name="email"
value={contact.email}
onChange={handleInputChange}
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
required
disabled
/>
</div>
<div className="mt-2.5">
<label
htmlFor="phone"
className="block text-xs text-gray-700 font-semibold"
>
{t("phone")}
</label>
<input
type="text"
name="phone"
value={contact.phone}
onChange={handleInputChange}
className="op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content w-full text-xs"
disabled={loading}
/>
</div>
<div className="mt-2 flex justify-start">
<button
type="submit"
className="op-btn op-btn-primary"
disabled={loading}
>
{loading ? t("loading") : t("next")}
</button>
</div>
</form>
</div>
)}
</div>
)}
</div>
)}
</div>
)}
</div>
<SelectLanguage />
</div>
);
}
+7 -1
View File
@@ -19,7 +19,7 @@ import Loader from "../primitives/Loader";
import { useTranslation } from "react-i18next";
import SelectLanguage from "../components/pdf/SelectLanguage";
function Login() {
const { t } = useTranslation();
const { t, i18n } = useTranslation();
const navigate = useNavigate();
const location = useLocation();
const dispatch = useDispatch();
@@ -115,8 +115,14 @@ function Login() {
`/${menu.pageType}/${menu.pageId}`;
let _role = _currentRole.replace("contracts_", "");
localStorage.setItem("_user_role", _role);
const checkLanguage = extUser?.get("Language");
if (checkLanguage) {
checkLanguage && i18n.changeLanguage(checkLanguage);
}
const results = [extUser];
const extUser_str = JSON.stringify(results);
localStorage.setItem("Extand_Class", extUser_str);
const extInfo = JSON.parse(JSON.stringify(extUser));
localStorage.setItem("userEmail", extInfo.Email);
+1 -1
View File
@@ -192,7 +192,7 @@ function Opensigndrive() {
setTourData(tourConfigs);
}
if (!docId) {
setFolderName([{ name: "OpenSign™ Drive", objectId: "" }]);
setFolderName([{ name: t("OpenSign-drive"), objectId: "" }]);
}
} catch (e) {
setIsAlert({
+2 -1
View File
@@ -208,11 +208,12 @@ function PdfRequestFiles(props) {
});
if (resEmail?.message === "Email is verified.") {
setIsEmailVerified(true);
alert(t("Email-verified-alert-1"));
} else if (resEmail?.message === "Email is already verified.") {
setIsEmailVerified(true);
alert(t("Email-verified-alert-2"));
}
setOtp("");
alert(resEmail.message);
setIsVerifyModal(false);
//handleRecipientSign();
} catch (error) {
+2 -2
View File
@@ -912,7 +912,7 @@ function PlaceHolderSign() {
if (!signatureExist) {
isSignatureExist = false;
setIsSendAlert({
mssg: t("sure"),
mssg: "sure",
alert: true
});
}
@@ -936,7 +936,7 @@ function PlaceHolderSign() {
}
} else {
setIsSendAlert({
mssg: t("sure"),
mssg: "sure",
alert: true
});
}
+2 -1
View File
@@ -593,11 +593,12 @@ function SignYourSelf() {
});
if (resEmail?.message === "Email is verified.") {
setIsEmailVerified(true);
alert(t("Email-verified-alert-1"));
} else if (resEmail?.message === "Email is already verified.") {
setIsEmailVerified(true);
alert(t("Email-verified-alert-2"));
}
setOtp("");
alert(resEmail.message);
setIsVerifyModal(false);
// handleRecipientSign();
} catch (error) {
+57 -40
View File
@@ -17,6 +17,7 @@ import Upgrade from "../primitives/Upgrade";
import ModalUi from "../primitives/ModalUi";
import Loader from "../primitives/Loader";
import { useTranslation } from "react-i18next";
import SelectLanguage from "../components/pdf/SelectLanguage";
function UserProfile() {
const navigate = useNavigate();
@@ -164,38 +165,43 @@ function UserProfile() {
// `updateExtUser` is used to update user details in extended class
const updateExtUser = async (obj) => {
const extData = JSON.parse(localStorage.getItem("Extand_Class"));
const ExtUserId = extData[0].objectId;
const body = {
Phone: obj?.Phone || "",
Name: obj.Name,
HeaderDocId: isDisableDocId,
JobTitle: jobTitle,
Company: company,
UserName: publicUserName || "",
Tagline: tagLine || ""
};
try {
const extData = JSON.parse(localStorage.getItem("Extand_Class"));
const ExtUserId = extData[0].objectId;
const body = {
Phone: obj?.Phone || "",
Name: obj.Name,
HeaderDocId: isDisableDocId,
JobTitle: jobTitle,
Company: company,
UserName: publicUserName || "",
Tagline: tagLine || "",
Language: obj?.language || ""
};
await axios.put(
parseBaseUrl + "classes/contracts_Users/" + ExtUserId,
body,
{
headers: {
"Content-Type": "application/json",
"X-Parse-Application-Id": parseAppId,
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
await axios.put(
parseBaseUrl + "classes/contracts_Users/" + ExtUserId,
body,
{
headers: {
"Content-Type": "application/json",
"X-Parse-Application-Id": parseAppId,
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
}
}
}
);
const res = await Parse.Cloud.run("getUserDetails", {
email: extData[0].Email
});
);
const res = await Parse.Cloud.run("getUserDetails", {
email: extData[0].Email
});
const json = JSON.parse(JSON.stringify([res]));
const extRes = JSON.stringify(json);
localStorage.setItem("Extand_Class", extRes);
previousPublicUserName.current = publicUserName;
// console.log("updateRes ", updateRes);
const json = JSON.parse(JSON.stringify([res]));
const extRes = JSON.stringify(json);
localStorage.setItem("Extand_Class", extRes);
previousPublicUserName.current = publicUserName;
// console.log("updateRes ", updateRes);
} catch (e) {
console.log("error in save data in contracts_Users class");
}
};
// file upload function
const fileUpload = async (file) => {
@@ -267,11 +273,12 @@ function UserProfile() {
});
if (resEmail?.message === "Email is verified.") {
setIsEmailVerified(true);
alert(t("Email-verified-alert-1"));
} else if (resEmail?.message === "Email is already verified.") {
setIsEmailVerified(true);
alert(t("Email-verified-alert-2"));
}
setOtp("");
alert(resEmail.message);
setIsVerifyModal(false);
} catch (error) {
alert(error.message);
@@ -359,6 +366,17 @@ function UserProfile() {
</div>
</div>
<ul className="w-full flex flex-col p-2 text-sm">
<li
className={`flex justify-between items-center border-t-[1px] border-gray-300 break-all ${
editmode ? "py-1.5" : "py-2"
}`}
>
<span className="font-semibold">{t("language")}:</span>{" "}
<SelectLanguage
isProfile={true}
updateExtUser={updateExtUser}
/>
</li>
<li
className={`flex justify-between items-center border-t-[1px] border-gray-300 break-all ${
editmode ? "py-1.5" : "py-2"
@@ -590,7 +608,7 @@ function UserProfile() {
{isVerifyModal && (
<ModalUi
isOpen
title={"OTP verification"}
title={t("otp-verification")}
handleClose={handleCloseVerifyModal}
>
{otpLoader ? (
@@ -600,26 +618,26 @@ function UserProfile() {
) : (
<form onSubmit={(e) => handleVerifyEmail(e)}>
<div className="px-6 py-3 text-base-content">
<label className="mb-2">Enter OTP</label>
<label className="mb-2">{t("enter-otp")}</label>
<input
required
type="tel"
pattern="[0-9]{4}"
className="w-full op-input op-input-bordered op-input-sm focus:outline-none hover:border-base-content text-xs"
placeholder="Enter OTP received over email"
placeholder={t("otp-placeholder")}
value={otp}
onChange={(e) => setOtp(e.target.value)}
/>
</div>
<div className="px-6 mb-3">
<button type="submit" className="op-btn op-btn-primary">
Verify
{t("verify")}
</button>
<button
className="op-btn op-btn-secondary ml-2"
onClick={(e) => handleResend(e)}
>
Resend
{t("resend")}
</button>
</div>
</form>
@@ -639,11 +657,10 @@ function UserProfile() {
<div className="op-card op-bg-primary text-primary-content w-full shadow-lg">
<div className="op-card-body">
<h2 className="op-card-title">Upgrade to Plan</h2>
<p>
To have a username less than 8 character please
subscribe
</p>
<h2 className="op-card-title">
{t("upgrade-to")} {t("plan")}
</h2>
<p>{t("user-name-limit-char")}</p>
<div className="op-card-actions justify-end">
<button
onClick={() => navigate("/subscription")}
@@ -0,0 +1,31 @@
/**
*
* @param {Parse} Parse
*/
exports.up = async Parse => {
// TODO: set className here
const className = 'contracts_Users';
const schema = new Parse.Schema(className);
schema.addString('Language');
// TODO: Set the schema here
// Example:
// schema.addString('name').addNumber('cash');
return schema.update();
};
/**
*
* @param {Parse} Parse
*/
exports.down = async Parse => {
// TODO: set className here
const className = 'contracts_Users';
const schema = new Parse.Schema(className);
schema.deleteField('Language');
// TODO: Set the schema here
// Example:
// schema.deleteField('name').deleteField('cash');
return schema.update();
};