Compare commits
10 Commits
78bdb1b275
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b162770e2d | ||
|
|
ce44293669 | ||
|
|
d6dd879db8 | ||
|
|
f15d01ba2c | ||
|
|
7b1df2d74b | ||
|
|
df5c49f4f0 | ||
|
|
514cee1487 | ||
|
|
33199f26ec | ||
|
|
3359c47379 | ||
|
|
1c5f16d42b |
@@ -21,7 +21,7 @@ COPY . .
|
||||
# Next.js collects completely anonymous telemetry data about general usage.
|
||||
# Learn more here: https://nextjs.org/telemetry
|
||||
# Uncomment the following line in case you want to disable telemetry during the build.
|
||||
# ENV NEXT_TELEMETRY_DISABLED 1
|
||||
ENV NEXT_TELEMETRY_DISABLED 1
|
||||
|
||||
ARG STRAPI_URL=http://localhost:1337
|
||||
ARG STRAPI_TOKEN=TOKEN
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
"react": "^18",
|
||||
"react-dom": "^18",
|
||||
"react-hook-form": "^7.50.1",
|
||||
"react-icons": "^4.11.0",
|
||||
"react-icons": "^5.1.0",
|
||||
"react-string-replace": "^1.1.1",
|
||||
"react-toastify": "^10.0.4",
|
||||
"sharp": "^0.32.6"
|
||||
|
||||
@@ -3,7 +3,7 @@ import About from "@/templates/About";
|
||||
import AboutPage from "@/types/cms/about";
|
||||
|
||||
export default async function Page() {
|
||||
const {data} = await getData<AboutPage>("about", "en");
|
||||
const data = await getData<AboutPage>("about", "en");
|
||||
|
||||
return <About data={data.data.attributes} language="en" />;
|
||||
return <About data={data} language="en" />;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import About from "@/templates/About";
|
||||
import AboutPage from "@/types/cms/about";
|
||||
|
||||
export default async function Page() {
|
||||
const {data} = await getData<AboutPage>("about", "ar");
|
||||
const data = await getData<AboutPage>("about", "ar");
|
||||
|
||||
return <About data={data.data.attributes} language="ar" />;
|
||||
return <About data={data} language="ar" />;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
import {getData} from "@/cms";
|
||||
import Footer from "@/components/Footer";
|
||||
import Navbar from "@/components/Navbar";
|
||||
import ContactUs from "@/templates/ContactUs";
|
||||
import ContactPage from "@/types/cms/contact";
|
||||
|
||||
export default async function Page() {
|
||||
const {data} = await getData<ContactPage>("contact", "ar");
|
||||
const data = await getData<ContactPage>("contact", "ar");
|
||||
|
||||
return <ContactUs data={data.data.attributes} page="/contact" language="ar" />;
|
||||
return (
|
||||
<main className="text-mti-black flex h-screen w-full flex-col bg-white" dir="rtl">
|
||||
<Navbar currentPage="/contact" language="ar" />
|
||||
<ContactUs data={data} />;
|
||||
<Footer language="ar" />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ export async function generateStaticParams() {
|
||||
}
|
||||
|
||||
export default async function Page({params: {country}}: PageProps) {
|
||||
const {data} = await getData<CountryManagerContactsPage>("country-managers-contact", language);
|
||||
const data = await getData<CountryManagerContactsPage>("country-managers-contact", language);
|
||||
|
||||
return <AgentContacts data={data.data.attributes} country={country} page={`/contacts/${country}`} language={language} />;
|
||||
return <AgentContacts data={data} country={country} page={`/contacts/${country}`} language={language} />;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import History from "@/templates/History";
|
||||
import HistoryPage from "@/types/cms/history";
|
||||
|
||||
export default async function Page() {
|
||||
const {data} = await getData<HistoryPage>("history", "ar");
|
||||
const data = await getData<HistoryPage>("history", "ar");
|
||||
|
||||
return <History data={data.data.attributes} language="ar" />;
|
||||
return <History data={data} language="ar" />;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
import {getData} from "@/cms";
|
||||
import Home from "@/templates/Home";
|
||||
import HomePage from "@/types/cms/home";
|
||||
import HomePage, {HomePageData} from "@/types/cms/home";
|
||||
import {NextPageContext} from "next";
|
||||
|
||||
export default async function Page() {
|
||||
const {data} = await getData<HomePage>("home", "ar");
|
||||
const data = await getData<HomePageData>("home", "ar");
|
||||
|
||||
return <Home data={data.data.attributes} language="ar" />;
|
||||
const home: HomePage = {
|
||||
...data,
|
||||
Banner: data?.Banner?.data?.attributes,
|
||||
AdvertisementBanner: data?.AdvertisementBanner?.data?.attributes,
|
||||
};
|
||||
|
||||
return <Home data={home} language="ar" />;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
import {getData} from "@/cms";
|
||||
import Footer from "@/components/Footer";
|
||||
import Navbar from "@/components/Navbar";
|
||||
import Price from "@/templates/Price";
|
||||
import PricePage from "@/types/cms/price";
|
||||
|
||||
export default async function Page() {
|
||||
const {data} = await getData<PricePage>("price", "ar");
|
||||
const data = await getData<PricePage>("price", "ar");
|
||||
|
||||
return <Price data={data.data.attributes} language="ar" />;
|
||||
return (
|
||||
<main className="h-screen w-full bg-white text-mti-black flex flex-col" dir="rtl">
|
||||
<Navbar currentPage="/price" language="ar" />
|
||||
<Price data={data} language="ar" />
|
||||
<Footer language="ar" />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import Terms from "@/templates/Terms";
|
||||
import PrivacyPolicyPage from "@/types/cms/privacyPolicy";
|
||||
|
||||
export default async function Page() {
|
||||
const {data} = await getData<PrivacyPolicyPage>("privacy-policy", "ar");
|
||||
const data = await getData<PrivacyPolicyPage>("privacy-policy", "ar");
|
||||
|
||||
return <Privacy data={data.data.attributes} language="ar" />;
|
||||
return <Privacy data={data} language="ar" />;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import Services from "@/templates/Services";
|
||||
import ServicesPage from "@/types/cms/services";
|
||||
|
||||
export default async function Page() {
|
||||
const {data} = await getData<ServicesPage>("services", "ar");
|
||||
const data = await getData<ServicesPage>("services", "ar");
|
||||
|
||||
return <Services data={data.data.attributes} language="ar" />;
|
||||
return <Services data={data} language="ar" />;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import Terms from "@/templates/Terms";
|
||||
import TermsAndConditionsPage from "@/types/cms/termsConditions";
|
||||
|
||||
export default async function Page() {
|
||||
const {data} = await getData<TermsAndConditionsPage>("terms-and-conditions", "ar");
|
||||
const data = await getData<TermsAndConditionsPage>("terms-and-conditions", "ar");
|
||||
|
||||
return <Terms data={data.data.attributes} language="ar" />;
|
||||
return <Terms data={data} language="ar" />;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
import {getData} from "@/cms";
|
||||
import Footer from "@/components/Footer";
|
||||
import Navbar from "@/components/Navbar";
|
||||
import ContactUs from "@/templates/ContactUs";
|
||||
import ContactPage from "@/types/cms/contact";
|
||||
|
||||
export default async function Page() {
|
||||
const {data} = await getData<ContactPage>("contact", "en");
|
||||
const data = await getData<ContactPage>("contact", "en");
|
||||
|
||||
return <ContactUs data={data.data.attributes} page="/contact" language="en" />;
|
||||
return (
|
||||
<main className="text-mti-black flex h-screen w-full flex-col bg-white" dir="ltr">
|
||||
<Navbar currentPage="/contact" language="en" />
|
||||
<ContactUs data={data} />;
|
||||
<Footer language="en" />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ export async function generateStaticParams() {
|
||||
}
|
||||
|
||||
export default async function Page({params: {country}}: PageProps) {
|
||||
const {data} = await getData<CountryManagerContactsPage>("country-managers-contact", language);
|
||||
const data = await getData<CountryManagerContactsPage>("country-managers-contact", language);
|
||||
|
||||
return <AgentContacts data={data.data.attributes} country={country} page={`/contacts/${country}`} language={language} />;
|
||||
return <AgentContacts data={data} country={country} page={`/contacts/${country}`} language={language} />;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import History from "@/templates/History";
|
||||
import HistoryPage from "@/types/cms/history";
|
||||
|
||||
export default async function Page() {
|
||||
const {data} = await getData<HistoryPage>("history", "en");
|
||||
const data = await getData<HistoryPage>("history", "en");
|
||||
|
||||
return <History data={data.data.attributes} language="en" />;
|
||||
return <History data={data} language="en" />;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
import {getData} from "@/cms";
|
||||
import Home from "@/templates/Home";
|
||||
import HomePage from "@/types/cms/home";
|
||||
import HomePage, {HomePageData} from "@/types/cms/home";
|
||||
import {NextPageContext} from "next";
|
||||
|
||||
export default async function Page() {
|
||||
const {data} = await getData<HomePage>("home", "en");
|
||||
const data = await getData<HomePageData>("home", "en");
|
||||
|
||||
return <Home data={data.data.attributes} language="en" />;
|
||||
const home: HomePage = {
|
||||
...data,
|
||||
Banner: data?.Banner?.data?.attributes,
|
||||
AdvertisementBanner: data?.AdvertisementBanner?.data?.attributes,
|
||||
};
|
||||
|
||||
return <Home data={home} language="en" />;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
import {getData} from "@/cms";
|
||||
import Footer from "@/components/Footer";
|
||||
import Navbar from "@/components/Navbar";
|
||||
import Price from "@/templates/Price";
|
||||
import PricePage from "@/types/cms/price";
|
||||
|
||||
export default async function Page() {
|
||||
const {data} = await getData<PricePage>("price", "en");
|
||||
const data = await getData<PricePage>("price", "en");
|
||||
|
||||
return <Price data={data.data.attributes} language="en" />;
|
||||
return (
|
||||
<main className="h-screen w-full bg-white text-mti-black flex flex-col" dir="ltr">
|
||||
<Navbar currentPage="/price" language="en" />
|
||||
<Price data={data} language="en" />
|
||||
<Footer language="en" />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import Terms from "@/templates/Terms";
|
||||
import PrivacyPolicyPage from "@/types/cms/privacyPolicy";
|
||||
|
||||
export default async function Page() {
|
||||
const {data} = await getData<PrivacyPolicyPage>("privacy-policy", "en");
|
||||
const data = await getData<PrivacyPolicyPage>("privacy-policy", "en");
|
||||
|
||||
return <Privacy data={data.data.attributes} language="en" />;
|
||||
return <Privacy data={data} language="en" />;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import Services from "@/templates/Services";
|
||||
import ServicesPage from "@/types/cms/services";
|
||||
|
||||
export default async function Page() {
|
||||
const {data} = await getData<ServicesPage>("services", "en");
|
||||
const data = await getData<ServicesPage>("services", "en");
|
||||
|
||||
return <Services data={data.data.attributes} language="en" />;
|
||||
return <Services data={data} language="en" />;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import Terms from "@/templates/Terms";
|
||||
import TermsAndConditionsPage from "@/types/cms/termsConditions";
|
||||
|
||||
export default async function Page() {
|
||||
const {data} = await getData<TermsAndConditionsPage>("terms-and-conditions", "en");
|
||||
const data = await getData<TermsAndConditionsPage>("terms-and-conditions", "en");
|
||||
|
||||
return <Terms data={data.data.attributes} language="en" />;
|
||||
return <Terms data={data} language="en" />;
|
||||
}
|
||||
|
||||
@@ -13,11 +13,12 @@ interface StrapiResponse<T> {
|
||||
meta: object;
|
||||
}
|
||||
|
||||
type Result<T> = {data: StrapiResponse<T>; isError: boolean};
|
||||
|
||||
export async function getData<T>(page: string, locale: "ar" | "en"): Promise<Result<T>> {
|
||||
export async function getData<T>(page: string, locale: "ar" | "en"): Promise<T> {
|
||||
const request = await axios.get<StrapiResponse<T>>(`${process.env.STRAPI_URL}/api/${page}/?populate=deep&locale=${locale}`, {
|
||||
headers: {Authorization: `Bearer ${process.env.STRAPI_TOKEN}`},
|
||||
});
|
||||
return {data: request.data, isError: request.status !== 200};
|
||||
|
||||
console.log('GetDAta', page, JSON.stringify(request.data.data.attributes, null, 2));
|
||||
return request.data.data.attributes;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,106 +1,119 @@
|
||||
import Link from "next/link";
|
||||
import {BiLogoFacebook} from "react-icons/bi";
|
||||
import {BsInstagram, BsTwitter} from "react-icons/bs";
|
||||
import { BiLogoFacebook } from "react-icons/bi";
|
||||
import { BsInstagram, BsTwitterX } from "react-icons/bs";
|
||||
import translation from "@/translation/footer.json";
|
||||
import clsx from "clsx";
|
||||
import FooterSection from "@/types/cms/footer";
|
||||
|
||||
interface Props {
|
||||
language: "en" | "ar";
|
||||
data: FooterSection;
|
||||
language: "en" | "ar";
|
||||
data: FooterSection;
|
||||
}
|
||||
|
||||
interface FooterLinkProps {
|
||||
language: "en" | "ar";
|
||||
children: string;
|
||||
href: string;
|
||||
language: "en" | "ar";
|
||||
children: string;
|
||||
href: string;
|
||||
}
|
||||
|
||||
const FooterLink = ({language, href, children}: FooterLinkProps) => {
|
||||
return <Link href={`${language === "ar" ? "/ar" : ""}${href}`}>{children}</Link>;
|
||||
const FooterLink = ({ language, href, children }: FooterLinkProps) => {
|
||||
return (
|
||||
<Link href={`${language === "ar" ? "/ar" : ""}${href}`}>{children}</Link>
|
||||
);
|
||||
};
|
||||
|
||||
export default function Footer({language, data}: Props) {
|
||||
return (
|
||||
<>
|
||||
<section className="bg-mti-gray-seasalt w-full">
|
||||
<div
|
||||
className={clsx(
|
||||
"w-full py-10 px-8 md:px-28 flex flex-col md:justify-between gap-8 lg:container lg:mx-auto",
|
||||
language === "ar" ? "md:flex-row-reverse" : "md:flex-row",
|
||||
)}>
|
||||
<div className="flex flex-col gap-4">
|
||||
<span className="font-bold text-xl">{data.Navigation.Text}</span>
|
||||
<div className="flex flex-col gap-2">
|
||||
<FooterLink language={language} href={`/about`}>
|
||||
{data.Navigation.WhyUs}
|
||||
</FooterLink>
|
||||
<FooterLink language={language} href={`/about#capabilities`}>
|
||||
{data.Navigation.Capabilities}
|
||||
</FooterLink>
|
||||
<FooterLink language={language} href={`/about#expertise`}>
|
||||
{data.Navigation.Expertise}
|
||||
</FooterLink>
|
||||
<FooterLink language={language} href="/history">
|
||||
{data.Navigation.History}
|
||||
</FooterLink>
|
||||
<FooterLink language={language} href="/contact">
|
||||
{data.Navigation.Contact}
|
||||
</FooterLink>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col gap-4">
|
||||
<span className="font-bold text-xl">{data.Services.Text}</span>
|
||||
<div className="flex flex-col gap-2">
|
||||
<FooterLink language={language} href="/#benefits">
|
||||
{data.Services.EnCoachBenefits}
|
||||
</FooterLink>
|
||||
<FooterLink language={language} href="#testimonials">
|
||||
{data.Services.StudentTestimonials}
|
||||
</FooterLink>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col gap-4">
|
||||
<span className="font-bold text-xl">{data.About.Text}</span>
|
||||
<div className="flex flex-col gap-2">
|
||||
<FooterLink language={language} href="/terms">
|
||||
{data.About.Terms}
|
||||
</FooterLink>
|
||||
<FooterLink language={language} href="/privacy-policy">
|
||||
{data.About.PrivacyPolicy}
|
||||
</FooterLink>
|
||||
<FooterLink language={language} href="/about">
|
||||
{data.About.Text}
|
||||
</FooterLink>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col gap-4">
|
||||
<span className="font-bold text-xl">{data.GetInTouch.Title}</span>
|
||||
<div className="flex flex-col gap-4">
|
||||
<span className="max-w-[280px]">{data.GetInTouch.Text}</span>
|
||||
<div className={clsx("flex gap-6 items-center", language === "ar" && "flex-row-reverse justify-start")}>
|
||||
<Link
|
||||
href="https://facebook.com"
|
||||
className="bg-mti-purple-ultralight rounded-full w-10 h-10 flex items-center justify-center hover:bg-mti-purple-dark text-mti-purple-light hover:text-white transition ease-in-out duration-300">
|
||||
<BiLogoFacebook className="w-6 h-6" />
|
||||
</Link>
|
||||
<Link
|
||||
href="https://twitter.com"
|
||||
className="bg-mti-purple-ultralight rounded-full w-10 h-10 flex items-center justify-center hover:bg-mti-purple-dark text-mti-purple-light hover:text-white transition ease-in-out duration-300">
|
||||
<BsTwitter className="w-5 h-5" />
|
||||
</Link>
|
||||
<Link
|
||||
href="https://instagram.com"
|
||||
className="bg-mti-purple-ultralight rounded-full w-10 h-10 flex items-center justify-center hover:bg-mti-purple-dark text-mti-purple-light hover:text-white transition ease-in-out duration-300">
|
||||
<BsInstagram className="w-5 h-5" />
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
export default function Footer({ language, data }: Props) {
|
||||
return (
|
||||
<>
|
||||
<section className="bg-mti-gray-seasalt w-full">
|
||||
<div
|
||||
className={clsx(
|
||||
"w-full py-10 px-8 md:px-28 flex flex-col md:justify-between gap-8 lg:container lg:mx-auto",
|
||||
language === "ar" ? "md:flex-row-reverse" : "md:flex-row",
|
||||
)}
|
||||
>
|
||||
<div className="flex flex-col gap-4">
|
||||
<span className="font-bold text-xl">{data.Navigation.Text}</span>
|
||||
<div className="flex flex-col gap-2">
|
||||
<FooterLink language={language} href={`/about`}>
|
||||
{data.Navigation.WhyUs}
|
||||
</FooterLink>
|
||||
<FooterLink language={language} href={`/about#capabilities`}>
|
||||
{data.Navigation.Capabilities}
|
||||
</FooterLink>
|
||||
<FooterLink language={language} href={`/about#expertise`}>
|
||||
{data.Navigation.Expertise}
|
||||
</FooterLink>
|
||||
<FooterLink language={language} href="/history">
|
||||
{data.Navigation.History}
|
||||
</FooterLink>
|
||||
<FooterLink language={language} href="/contact">
|
||||
{data.Navigation.Contact}
|
||||
</FooterLink>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col gap-4">
|
||||
<span className="font-bold text-xl">{data.Services.Text}</span>
|
||||
<div className="flex flex-col gap-2">
|
||||
<FooterLink language={language} href="/#benefits">
|
||||
{data.Services.EnCoachBenefits}
|
||||
</FooterLink>
|
||||
<FooterLink language={language} href="#testimonials">
|
||||
{data.Services.StudentTestimonials}
|
||||
</FooterLink>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col gap-4">
|
||||
<span className="font-bold text-xl">{data.About.Text}</span>
|
||||
<div className="flex flex-col gap-2">
|
||||
<FooterLink language={language} href="/terms">
|
||||
{data.About.Terms}
|
||||
</FooterLink>
|
||||
<FooterLink language={language} href="/privacy-policy">
|
||||
{data.About.PrivacyPolicy}
|
||||
</FooterLink>
|
||||
<FooterLink language={language} href="/about">
|
||||
{data.About.Text}
|
||||
</FooterLink>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col gap-4">
|
||||
<span className="font-bold text-xl">{data.GetInTouch.Title}</span>
|
||||
<div className="flex flex-col gap-4">
|
||||
<span className="max-w-[280px]">{data.GetInTouch.Text}</span>
|
||||
<div
|
||||
className={clsx(
|
||||
"flex gap-6 items-center",
|
||||
language === "ar" && "flex-row-reverse justify-start",
|
||||
)}
|
||||
>
|
||||
<Link
|
||||
href="https://facebook.com"
|
||||
className="bg-mti-purple-ultralight rounded-full w-10 h-10 flex items-center justify-center hover:bg-mti-purple-dark text-mti-purple-light hover:text-white transition ease-in-out duration-300"
|
||||
>
|
||||
<BiLogoFacebook className="w-6 h-6" />
|
||||
</Link>
|
||||
<Link
|
||||
href="https://twitter.com"
|
||||
className="bg-mti-purple-ultralight rounded-full w-10 h-10 flex items-center justify-center hover:bg-mti-purple-dark text-mti-purple-light hover:text-white transition ease-in-out duration-300"
|
||||
>
|
||||
<BsTwitterX className="w-5 h-5" />
|
||||
</Link>
|
||||
<Link
|
||||
href="https://instagram.com"
|
||||
className="bg-mti-purple-ultralight rounded-full w-10 h-10 flex items-center justify-center hover:bg-mti-purple-dark text-mti-purple-light hover:text-white transition ease-in-out duration-300"
|
||||
>
|
||||
<BsInstagram className="w-5 h-5" />
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<footer className="w-full py-10 bg-mti-rose-light text-white flex items-center justify-center">© {data.Copyright}</footer>
|
||||
</>
|
||||
);
|
||||
<footer className="w-full py-10 bg-mti-rose-light text-white flex items-center justify-center">
|
||||
© {data.Copyright}
|
||||
</footer>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ interface Props {
|
||||
}
|
||||
|
||||
export default async function FooterContainer({language}: Props) {
|
||||
const {data} = await getData<FooterSection>("footer", language);
|
||||
const data = await getData<FooterSection>("footer", language);
|
||||
|
||||
return <Footer data={data.data.attributes} language={language} />;
|
||||
return <Footer data={data} language={language} />;
|
||||
}
|
||||
|
||||
@@ -117,6 +117,11 @@ export default function Navbar({currentPage, language, data}: Props) {
|
||||
)}
|
||||
</div>
|
||||
<div className="flex w-fit items-center gap-4">
|
||||
<Link
|
||||
href="https://platform.encoach.com/official-exam"
|
||||
className="hover:bg-mti-purple-dark border-mti-purple-dark rounded-xl border px-8 py-2 transition duration-300 ease-in-out hover:text-white">
|
||||
Official Exam
|
||||
</Link>
|
||||
<Link
|
||||
href="https://platform.encoach.com"
|
||||
className="hover:bg-mti-purple-dark border-mti-purple-dark rounded-xl border px-8 py-2 transition duration-300 ease-in-out hover:text-white">
|
||||
|
||||
@@ -8,7 +8,7 @@ interface Props {
|
||||
}
|
||||
|
||||
export default async function NavbarContainer({currentPage, language}: Props) {
|
||||
const {data} = await getData<NavBarSection>("nav-bar", language);
|
||||
const data = await getData<NavBarSection>("nav-bar", language);
|
||||
|
||||
return <Navbar data={data.data.attributes} language={language} currentPage={currentPage} />;
|
||||
return <Navbar data={data} language={language} currentPage={currentPage} />;
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ export async function AgentContacts({language, page, country, data}: Props) {
|
||||
const contact = (await getCountryManagers(country, language)) as Contact;
|
||||
|
||||
return (
|
||||
<main className="text-mti-black flex h-screen w-full flex-col bg-white">
|
||||
<main className="text-mti-black flex h-screen w-full flex-col bg-white" dir={language === "ar" ? "rtl" : "ltr"}>
|
||||
<Navbar currentPage={page} language={language} />
|
||||
|
||||
<section className="bg-mti-purple h-full w-full p-8 text-center text-white md:p-16">
|
||||
|
||||
@@ -18,9 +18,7 @@ type FormValues = {
|
||||
};
|
||||
|
||||
interface Props {
|
||||
language: "en" | "ar";
|
||||
data: ContactPage;
|
||||
page: string;
|
||||
}
|
||||
|
||||
const ErrorMessage = ({message}: {message: string}) => (
|
||||
@@ -28,7 +26,7 @@ const ErrorMessage = ({message}: {message: string}) => (
|
||||
<span className="text-mti-red">{message}</span>
|
||||
</div>
|
||||
);
|
||||
export default function App({language, data, page}: Props) {
|
||||
export default function App({data}: Props) {
|
||||
const selectOptions = [
|
||||
{
|
||||
label: data.Feedback,
|
||||
@@ -92,67 +90,63 @@ export default function App({language, data, page}: Props) {
|
||||
return (
|
||||
<>
|
||||
<ToastContainer />
|
||||
<main className="text-mti-black flex h-screen w-full flex-col bg-white" dir={language === "ar" ? "rtl" : "ltr"}>
|
||||
<Navbar currentPage={page} language={language} />
|
||||
<section className="w-full bg-mti-purple text-white text-center p-8 md:p-16">
|
||||
<div className="w-full h-full flex flex-col items-center justify-center">
|
||||
<Title>{data.Title}</Title>
|
||||
</div>
|
||||
</section>
|
||||
<section className="w-full bg-white text-center p-8 md:p-16 flex justify-center items-center gap-32">
|
||||
<form onSubmit={handleSubmit(onSubmit)} className="form-control items-center gap-2 text-mti-black flex flex-col w-96">
|
||||
<input
|
||||
id="name"
|
||||
type="text"
|
||||
placeholder={data.Name}
|
||||
{...register("name", {required: true})}
|
||||
className="input input-bordered md:w-full sm:w-1/2 max-w-md"
|
||||
/>
|
||||
{errors.name && errors.name.type === "required" && <ErrorMessage message={data.FieldRequired} />}
|
||||
<input
|
||||
id="email"
|
||||
placeholder={data.Email}
|
||||
type="text"
|
||||
{...register("email", {required: true, pattern: /^\S+@\S+$/i})}
|
||||
className="input input-bordered md:w-full sm:w-1/2 max-w-md"
|
||||
/>
|
||||
{errors.email && errors.email.type === "required" && <ErrorMessage message={data.FieldRequired} />}
|
||||
{errors.email && errors.email.type === "pattern" && <ErrorMessage message={data.InvalidEmail} />}
|
||||
<input
|
||||
id="subject"
|
||||
placeholder={data.Subject}
|
||||
type="text"
|
||||
{...register("subject", {required: true})}
|
||||
className="input input-bordered md:w-full sm:w-1/2 max-w-md"
|
||||
/>
|
||||
{errors.subject && errors.subject.type === "required" && <ErrorMessage message={data.FieldRequired} />}
|
||||
<select id="type" {...register("type", {required: true})} className="select select-bordered md:w-full sm:w-1/2 max-w-md">
|
||||
<option value="" disabled>
|
||||
{data.SelectType}
|
||||
<section className="w-full bg-mti-purple text-white text-center p-8 md:p-16">
|
||||
<div className="w-full h-full flex flex-col items-center justify-center">
|
||||
<Title>{data.Title}</Title>
|
||||
</div>
|
||||
</section>
|
||||
<section className="w-full bg-white text-center p-8 md:p-16 flex justify-center items-center gap-32">
|
||||
<form onSubmit={handleSubmit(onSubmit)} className="form-control items-center gap-2 text-mti-black flex flex-col w-96">
|
||||
<input
|
||||
id="name"
|
||||
type="text"
|
||||
placeholder={data.Name}
|
||||
{...register("name", {required: true})}
|
||||
className="input input-bordered md:w-full sm:w-1/2 max-w-md"
|
||||
/>
|
||||
{errors.name && errors.name.type === "required" && <ErrorMessage message={data.FieldRequired} />}
|
||||
<input
|
||||
id="email"
|
||||
placeholder={data.Email}
|
||||
type="text"
|
||||
{...register("email", {required: true, pattern: /^\S+@\S+$/i})}
|
||||
className="input input-bordered md:w-full sm:w-1/2 max-w-md"
|
||||
/>
|
||||
{errors.email && errors.email.type === "required" && <ErrorMessage message={data.FieldRequired} />}
|
||||
{errors.email && errors.email.type === "pattern" && <ErrorMessage message={data.InvalidEmail} />}
|
||||
<input
|
||||
id="subject"
|
||||
placeholder={data.Subject}
|
||||
type="text"
|
||||
{...register("subject", {required: true})}
|
||||
className="input input-bordered md:w-full sm:w-1/2 max-w-md"
|
||||
/>
|
||||
{errors.subject && errors.subject.type === "required" && <ErrorMessage message={data.FieldRequired} />}
|
||||
<select id="type" {...register("type", {required: true})} className="select select-bordered md:w-full sm:w-1/2 max-w-md">
|
||||
<option value="" disabled>
|
||||
{data.SelectType}
|
||||
</option>
|
||||
{selectOptions.map((option) => (
|
||||
<option key={option.value} value={option.value}>
|
||||
{option.label}
|
||||
</option>
|
||||
{selectOptions.map((option) => (
|
||||
<option key={option.value} value={option.value}>
|
||||
{option.label}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
{errors.type && errors.type.type === "required" && <ErrorMessage message={data.FieldRequired} />}
|
||||
<textarea
|
||||
id="description"
|
||||
placeholder={data.Description}
|
||||
{...register("description", {required: true})}
|
||||
className="textarea textarea-bordered md:w-full sm:w-1/2 max-w-md"
|
||||
rows={5}
|
||||
/>
|
||||
{errors.description && errors.description.type === "required" && <ErrorMessage message={data.FieldRequired} />}
|
||||
<input type="submit" className="btn" disabled={!isDirty || !isValid} value={data.Submit} />
|
||||
</form>
|
||||
<div className="flex flex-col">
|
||||
<Image src="/person_laptop_focus.jpg" alt="Contact Us" width={500} height={340} className="rounded-xl" />
|
||||
</div>
|
||||
</section>
|
||||
<Footer language={language} />
|
||||
</main>
|
||||
))}
|
||||
</select>
|
||||
{errors.type && errors.type.type === "required" && <ErrorMessage message={data.FieldRequired} />}
|
||||
<textarea
|
||||
id="description"
|
||||
placeholder={data.Description}
|
||||
{...register("description", {required: true})}
|
||||
className="textarea textarea-bordered md:w-full sm:w-1/2 max-w-md"
|
||||
rows={5}
|
||||
/>
|
||||
{errors.description && errors.description.type === "required" && <ErrorMessage message={data.FieldRequired} />}
|
||||
<input type="submit" className="btn" disabled={!isDirty || !isValid} value={data.Submit} />
|
||||
</form>
|
||||
<div className="flex flex-col">
|
||||
<Image src="/person_laptop_focus.jpg" alt="Contact Us" width={500} height={340} className="rounded-xl" />
|
||||
</div>
|
||||
</section>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -20,9 +20,21 @@ export default function Home({language, data}: Props) {
|
||||
className={clsx("h-screen w-full bg-white text-mti-black flex flex-col", language === "ar" && "text-right")}
|
||||
dir={language === "ar" ? "rtl" : "ltr"}>
|
||||
<Navbar currentPage="/" language={language} />
|
||||
|
||||
{data.AdvertisementBanner?.url && (
|
||||
<section className="w-full relative bg-white mb-4">
|
||||
<img
|
||||
src={data.AdvertisementBanner.url}
|
||||
alt={data.AdvertisementBanner.alternativeText || 'Advertisement Banner'}
|
||||
className="w-full"
|
||||
/>
|
||||
</section>
|
||||
)}
|
||||
<section className="w-full relative bg-white">
|
||||
<img src="/banner_encoach_home.png" alt="IELTS Packages - Together we prepare for the future" className="w-full" />
|
||||
<img
|
||||
src={data.Banner?.url || "/banner_encoach_home.png"}
|
||||
alt={data.Banner?.alternativeText ?? "IELTS Packages - Together we prepare for the future"}
|
||||
className="w-full"
|
||||
/>
|
||||
<Link href={language === "ar" ? "/ar/price" : "/price"}>
|
||||
<button className="absolute bottom-1/12 -lg:hidden left-1/12 bg-mti-purple-light hover:bg-mti-purple text-white rounded-xl px-8 py-4 transition ease-in-out duration-300 shadow">
|
||||
{data.GetStartedButton}
|
||||
|
||||
@@ -67,8 +67,7 @@ export default function Page({language, data}: Props) {
|
||||
getData();
|
||||
}, []);
|
||||
return (
|
||||
<main className="h-screen w-full bg-white text-mti-black flex flex-col" dir={language === "ar" ? "rtl" : "ltr"}>
|
||||
<Navbar currentPage="/price" language={language} />
|
||||
<>
|
||||
<section className="w-full relative bg-white px-8 flex flex-col items-center text-center gap-4">
|
||||
<h2 className="text-3xl font-bold">{data.Title}</h2>
|
||||
<div className="grid grid-cols-2 gap-8">
|
||||
@@ -103,7 +102,6 @@ export default function Page({language, data}: Props) {
|
||||
{data.SignUp}
|
||||
</Link>
|
||||
</section>
|
||||
<Footer language={language} />
|
||||
</main>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -13,3 +13,24 @@ export type TitleWithTagAndText = TagTitle & TitleWithText;
|
||||
export interface TitleWithTextAndList extends TitleWithText {
|
||||
List: string;
|
||||
}
|
||||
|
||||
export interface ImageData {
|
||||
data: {
|
||||
id: number;
|
||||
attributes: Image;
|
||||
};
|
||||
}
|
||||
|
||||
export interface Image {
|
||||
name: string;
|
||||
alternativeText: string | null;
|
||||
caption: string | null;
|
||||
width: number;
|
||||
height: number;
|
||||
hash: string;
|
||||
ext: string;
|
||||
mime: string;
|
||||
size: number;
|
||||
url: string;
|
||||
previewUrl: string | null;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {TagTitle, TitleWithTagAndText, TitleWithText} from "./common";
|
||||
import {TagTitle, TitleWithTagAndText, TitleWithText, ImageData, Image} from "./common";
|
||||
|
||||
export default interface HomePage {
|
||||
interface Base {
|
||||
GetStartedButton: string;
|
||||
Modules: Modules;
|
||||
LearnAI: TitleWithTagAndText;
|
||||
@@ -12,6 +12,16 @@ export default interface HomePage {
|
||||
Accreditation: string;
|
||||
}
|
||||
|
||||
export default interface HomePage extends Base {
|
||||
Banner: Image;
|
||||
AdvertisementBanner: Image;
|
||||
}
|
||||
|
||||
export interface HomePageData extends Base {
|
||||
Banner: ImageData;
|
||||
AdvertisementBanner: ImageData;
|
||||
}
|
||||
|
||||
interface Modules {
|
||||
Reading: TitleWithText;
|
||||
Listening: TitleWithText;
|
||||
|
||||
@@ -2263,10 +2263,10 @@ react-hook-form@^7.50.1:
|
||||
resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.50.1.tgz#f6aeb17a863327e5a0252de8b35b4fc8990377ed"
|
||||
integrity sha512-3PCY82oE0WgeOgUtIr3nYNNtNvqtJ7BZjsbxh6TnYNbXButaD5WpjOmTjdxZfheuHKR68qfeFnEDVYoSSFPMTQ==
|
||||
|
||||
react-icons@^4.11.0:
|
||||
version "4.11.0"
|
||||
resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-4.11.0.tgz#4b0e31c9bfc919608095cc429c4f1846f4d66c65"
|
||||
integrity sha512-V+4khzYcE5EBk/BvcuYRq6V/osf11ODUM2J8hg2FDSswRrGvqiYUYPRy4OdrWaQOBj4NcpJfmHZLNaD+VH0TyA==
|
||||
react-icons@^5.1.0:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-5.1.0.tgz#9e7533cc256571a610c2a1ec8a7a143fb1222943"
|
||||
integrity sha512-D3zug1270S4hbSlIRJ0CUS97QE1yNNKDjzQe3HqY0aefp2CBn9VgzgES27sRR2gOvFK+0CNx/BW0ggOESp6fqQ==
|
||||
|
||||
react-is@^16.13.1:
|
||||
version "16.13.1"
|
||||
|
||||
Reference in New Issue
Block a user