mirror of
https://github.com/OpenSignLabs/OpenSign.git
synced 2026-08-20 06:35:54 +02:00
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:
@@ -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")}:{" "}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
})}
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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" },
|
||||
};
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -192,7 +192,7 @@ function Opensigndrive() {
|
||||
setTourData(tourConfigs);
|
||||
}
|
||||
if (!docId) {
|
||||
setFolderName([{ name: "OpenSign™ Drive", objectId: "" }]);
|
||||
setFolderName([{ name: t("OpenSign-drive"), objectId: "" }]);
|
||||
}
|
||||
} catch (e) {
|
||||
setIsAlert({
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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")}
|
||||
|
||||
+31
@@ -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();
|
||||
};
|
||||
Reference in New Issue
Block a user