Skip to content

Commit

Permalink
Dev -> Canary (#349)
Browse files Browse the repository at this point in the history
* scraped static texts on all pages

* got text from modals as well

* added common languages offered

* setting up redux for manual language selection

* hooked dropdown to redux data

* feat: lang selection working with dummy data set. Selection persists too

* whole of homepage now depends on static text object

* interactions, comment box, events and testimonial section all looking good

* one testimonial, one events page 🔥

* several changes json object for static text and testing with dummy translations

* language is now automatically added to apiCall

* fixed bug with comment component translation

* more translations, and tweaks to page json structure

* testimonial form now translated too

* getting started with languages offered page

* still setting up multi select on dropdown. checkbox in dropdown is not checking yet

* removing language works locally

* setup admin lang selector and docked it at the top of campaign edit page

* dropdown for language context on admin side now works with admin selected languages

* remove log

* Now changed to toggles

* removed comments and added translation for fallback text

* removed logs

* edited toggles

* add language back in there

* sort languages

* translated more fallback texts

* translated preview mode & events too

* paused on admin tans for now

* removed comments and limited languages

* now loads language list from api

* better config log

* version number bump

* point to dev

* Bump BUILD_VERSION to 1.1.1

* user language

* remove about

* version number resolution

* upgrade

* Bump BUILD_VERSION to 1.1.4

* en-us

* Bump BUILD_VERSION to 1.1.5

* toggling languages works for admins

* client side loads from toggle list

* dont show ribbon when no list is provided

* dash will be provided if only one enabled language

* fix nav issue

* english cant be toggled, several tweaks to frontend logic

* pre testimonial translations setup for homepage area

* translated more dialogs

* resolved some circular imports

* cp for language selectino modal

* language modal setup with several bug fixes also done

* fixed testimonial form translation & height issues

* now added flags

* Bump BUILD_VERSION to 1.1.6

* squashed conflicts

* Bump BUILD_VERSION to 1.1.7

* added caret

* fixed single and no language logic

* bump

* Bump BUILD_VERSION to 1.1.9

* now looks for language only when data is loaded

* removed logs

* optional lang

* Bump BUILD_VERSION to 1.1.10

* made messenger pull from local storage (#347)

* Bump BUILD_VERSION to 1.1.11

* Prevent language override for admin users

This change ensures that the user language parameter is not appended to the API call when the user is an admin. This avoids any conflict or unintended behavior for admin-level operations, enhancing the robustness of language handling in the messaging API.

* Add optional chaining in various string splitting operations

Refactor the code to use optional chaining for string split operations to ensure error prevention on null or undefined values. This change improves the robustness of the code, particularly for scenarios where split might be called on potentially nullable strings.

* Bump BUILD_VERSION to 1.1.12

---------

Co-authored-by: Version Update Bot <[email protected]>
Co-authored-by: Tahiru Abdullai <[email protected]>
  • Loading branch information
3 people authored Aug 19, 2024
1 parent 8bff95b commit f661475
Show file tree
Hide file tree
Showing 62 changed files with 3,125 additions and 546 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,5 @@ npm-debug.log*
yarn-debug.log*
yarn-error.log*
.idea/
.env.development
.env.development
87 changes: 45 additions & 42 deletions src/admin-portal/create-campaign/campaign-details-and-preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,18 @@ import LandingPage from "../../user-portal/pages/landing-page/LandingPage";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faExternalLink } from "@fortawesome/free-solid-svg-icons";
import { useCampaignContext } from "../../hooks/use-campaign-context";
import ToggleLanguage from "../internationalization/ToggleLanguage";

export function CampaignDetailsAndPreview ({setStep,}) {
export function CampaignDetailsAndPreview({ setStep }) {
const [activeTab, setActiveTab] = useState(campaignPages[0].name);
const [preview, setPreview] = useState(false);

const {campaignDetails,originalCampaignDetails,lists,handleCampaignDetailsChange : setCampaignDetails} = useCampaignContext();
const {
campaignDetails,
originalCampaignDetails,
lists,
handleCampaignDetailsChange: setCampaignDetails,
} = useCampaignContext();

return (
<>
Expand All @@ -20,11 +26,15 @@ export function CampaignDetailsAndPreview ({setStep,}) {
<h4 className="mb-0">{campaignDetails.title}</h4>
</Col>
<div className="text-right col-auto px-4">
{/* <ToggleLanguage campaignId={campaignDetails?.id} /> */}
<ButtonGroup className="mr-2">
<Button variant="primary" onClick={() => {
window.open(`/campaign/${campaignDetails.slug}?preview=true`, "_blank")
}}>
Preview <FontAwesomeIcon icon={faExternalLink}/>
<Button
variant="primary"
onClick={() => {
window.open(`/campaign/${campaignDetails.slug}?preview=true`, "_blank");
}}
>
Preview <FontAwesomeIcon icon={faExternalLink} />
</Button>
</ButtonGroup>
</div>
Expand All @@ -36,18 +46,15 @@ export function CampaignDetailsAndPreview ({setStep,}) {
<Row className="pb-2 overflow-x-auto">
<Col className={"px-4"}>
<div className="nav-tabs-container">
{
campaignPages?.map((page) => (
<div
key={page?.name}
className={classes("nav-tabs-main tab", { "tab-active": activeTab === page?.name })}
onClick={() => setActiveTab(page?.name)}
>
<h5 className={classes("nav-tabs",)}>
{page?.name}
</h5>
</div>
))}
{campaignPages?.map((page) => (
<div
key={page?.name}
className={classes("nav-tabs-main tab", { "tab-active": activeTab === page?.name })}
onClick={() => setActiveTab(page?.name)}
>
<h5 className={classes("nav-tabs")}>{page?.name}</h5>
</div>
))}
</div>
</Col>
</Row>
Expand All @@ -56,33 +63,29 @@ export function CampaignDetailsAndPreview ({setStep,}) {
{/*region Body: Content goes here*/}
<Row className=" pt-4">
<Col className={"px-4"}>
{
campaignPages?.map((tab) => {
return (
activeTab === tab?.name && (
<tab.component
key={tab?.name}
setStep={setStep}
campaignDetails={campaignDetails}
originalCampaignDetails={originalCampaignDetails}
setCampaignDetails={setCampaignDetails}
lists={lists}
/>
)
);
})}
{campaignPages?.map((tab) => {
return (
activeTab === tab?.name && (
<tab.component
key={tab?.name}
setStep={setStep}
campaignDetails={campaignDetails}
originalCampaignDetails={originalCampaignDetails}
setCampaignDetails={setCampaignDetails}
lists={lists}
/>
)
);
})}
</Col>
</Row>

</Col>
{
preview && (
<Col className={"position-relative"}>
<LandingPage campaign={campaignDetails} preview/>
</Col>
)
}
{preview && (
<Col className={"position-relative"}>
<LandingPage campaign={campaignDetails} preview />
</Col>
)}
</Row>
</>
)
);
}
156 changes: 156 additions & 0 deletions src/admin-portal/internationalization/AddOfferedLanguages.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import React, { useEffect, useState } from "react";
import { AdminLayout } from "../../layouts/admin-layout";
import { Container, Row, ToggleButton } from "react-bootstrap";
import { MultiSelect } from "react-multi-select-component";
import { LANGUAGES } from "../../utils/internationalization/languages";
import { useDispatch, useSelector } from "react-redux";
import { loadLanguagesAction, updateOfferedLanguageAction } from "src/redux/actions/actions";
import Button from "src/components/admin-components/Button";
import ToggleSwitch from "src/components/toggle-switch/ToggleSwitch";
import Loading from "src/components/pieces/Loading";
import { apiCall } from "src/api/messenger";
export const getOfferedForThisCampaign = (objFromRedux, id) => {
if (!objFromRedux) return DEFAULT_OFFERED_PER_CAMPAIGN;
return objFromRedux[id];
};

const DEFAULT_OFFERED_PER_CAMPAIGN = [{ label: "English (US)", value: "en-US" }];
function AddOfferedLanguages({ campaignDetails: campaign }) {
const [loading, setLoading] = useState(false);
const [updateLoading, setUpdateLoading] = useState(false);
const [error, setError] = useState("");
const [trackChanges, setChanges] = useState({});
const languages = useSelector((state) => state?.languageList);
languages?.sort((a, b) => a?.name?.localeCompare(b?.name));

// const cOffered = useSelector((state) => state?.campaignOfferedLanguages);
const dispatch = useDispatch();
const campaignId = campaign?.id;

const putLanguageListInRedux = (data) => {
return dispatch(loadLanguagesAction(data));
};

const includeNewLanguage = (key, status) => {
setChanges({ ...trackChanges, [key]: status });
};

const pushChanges = () => {
setUpdateLoading(true);
const body = { campaign_id: campaignId, supported_languages: JSON.stringify(trackChanges) };
apiCall("campaigns.supported_languages.update", body).then((res) => {
setUpdateLoading(false);
if (!res?.success) return console.log("Error Saving Changes: ", res?.error);
putLanguageListInRedux(res?.data);
});
};

const fetchEssentials = () => {
Promise.all([apiCall("campaigns.supported_languages.list", { campaign_id: campaignId })]).then(([langList]) => {
setLoading(false);
if (!langList?.success) {
return setError(langList?.error || "Sorry, could not load list of languages");
}
putLanguageListInRedux(langList?.data);
// updateInRedux(offeredList?.data);
});
};

useEffect(() => {
if (!languages?.length) fetchEssentials();
else setLoading(false);
}, []);

if (error) return <p style={{ width: "100%", textAlign: "center", fontWeight: "bold", color: "#df5555" }}>{error}</p>;
if (loading) return <Loading text="Fetching languages...." />;

return (
// <AdminLayout>
<div style={{ padding: "" }}>
<Row style={{ height: "100vh" }}>
{/* <Row style={{}}> */}
{/* <h3>Add Offered Languages</h3> */}
<p>Add all the translation languages that you want to offer on your campaign site here</p>
<div style={{ height: "100%", marginTop: 20 }}>
{/* <div style={{ marginTop: 20 }}> */}
{/* <MultiSelect
multiple
value={offered}
options={(languages || []).map(([value, label]) => {
return {
value,
label,
};
})}
onChange={(vals) => updateInRedux(vals)}
valueRenderer={(selected, _options) => {
if (selected.length === 0) return "Select languages";
if (selected.length === _options.length) return "All languages selected";
if (selected.length > 5) return `${selected.length} languages Selected`;
return selected
?.map(({ label }) => label)
.join(", ")
.concat(" Selected");
}}
labelledBy="Select"
/> */}

<div
style={{
// height: "100%",
width: "100%",
background: "rgb(248 248 248 / 44%)",
borderRadius: 10,
minHeight: 200,
marginTop: 10,
padding: 30,
}}
>
<div style={{ display: "flex", flexDirection: "row", paddingBottom: 20 }}>
<h5 style={{ display: "inline", color: "#d8d8d8" }}>LANGUAGES</h5>
<h5 style={{ marginLeft: "auto", display: "inline", color: "#d8d8d8" }}>Toggle ON/OFF</h5>
</div>
{languages?.map(({ name: label, code: k, is_active }) => {
const isEnglish = k === "en-US";
return (
<h6
// className="touchable-opacity"
style={{
marginBottom: 15,
paddingBottom: 7,
display: "flex",
flexDirection: "row",
alignItems: "center",
border: "solid 0px #e9e9e9",
borderBottomWidth: 2,
}}
>
{label}

<div style={{ marginLeft: "auto" }}>
{!isEnglish && <ToggleSwitch onChange={(state) => includeNewLanguage(k, state)} ON={is_active} />}
</div>
{/* <span
onClick={() => removeLang(lang?.value)}
style={{ marginLeft: "auto", color: "#c83131", fontSize: 16 }}
>
Remove
</span> */}
</h6>
);
})}
</div>

<div style={{ padding: "20px 00px" }}>
<Button loading={updateLoading} onClick={() => pushChanges()}>
Save
</Button>
</div>
</div>
</Row>
</div>
// </AdminLayout>
);
}

export default AddOfferedLanguages;
40 changes: 40 additions & 0 deletions src/admin-portal/internationalization/ToggleLanguage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React from "react";
import { useSelector } from "react-redux";
import { getOfferedForThisCampaign } from "./AddOfferedLanguages";

function ToggleLanguage({ campaignId }) {
const offeredLangs = useSelector((state) => state?.campaignOfferedLanguages);
const content = getOfferedForThisCampaign(offeredLangs, campaignId);

return (
// <div className="l-drop">
<div style={{ display: "inline-flex", flexDirection: "column" }}>
<div className="l-drop">
<select
// value={activeLanguage}
onChange={(e) => {
// const langs = Object.keys(offeredLangs || {});
// const key = e?.target?.value; // languageISO
// const obj = langs.find((k) => k === key);
// setActiveLanguage(obj);
}}
// style={{ textTransform: "uppercase" }}
className="undefault"
>
{/* {Object.entries(offeredLangs || {})?.map(([key, name]) => ( */}
{content?.map(({ label }, key) => (
<option key={key} value={key} style={{ width: "100%" }}>
{/* {smartString(name, 12)} */}
{label}
</option>
))}
</select>
</div>
<small style={{ fontSize: 11, marginTop: 10, color: "grey", textAlign: "center" }}>
Select the language you want to create content in
</small>
</div>
);
}

export default ToggleLanguage;
Loading

0 comments on commit f661475

Please sign in to comment.