Final touches

This commit is contained in:
2024-06-11 19:07:43 +01:00
parent 0f32c5441d
commit ae34843303
13 changed files with 252 additions and 24 deletions
+13
View File
@@ -0,0 +1,13 @@
FROM node:18-alpine
# Path: /app
WORKDIR /lk-results/
COPY . .
RUN npm install
RUN npm run build
RUN npm install -g serve
CMD ["serve", "-s", "build"]
+11 -7
View File
@@ -1813,12 +1813,13 @@
} }
}, },
"node_modules/braces": { "node_modules/braces": {
"version": "3.0.2", "version": "3.0.3",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"dev": true, "dev": true,
"license": "MIT",
"dependencies": { "dependencies": {
"fill-range": "^7.0.1" "fill-range": "^7.1.1"
}, },
"engines": { "engines": {
"node": ">=8" "node": ">=8"
@@ -2517,10 +2518,11 @@
} }
}, },
"node_modules/fill-range": { "node_modules/fill-range": {
"version": "7.0.1", "version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"dev": true, "dev": true,
"license": "MIT",
"dependencies": { "dependencies": {
"to-regex-range": "^5.0.1" "to-regex-range": "^5.0.1"
}, },
@@ -2901,6 +2903,7 @@
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true, "dev": true,
"license": "MIT",
"engines": { "engines": {
"node": ">=0.12.0" "node": ">=0.12.0"
} }
@@ -4204,6 +4207,7 @@
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true, "dev": true,
"license": "MIT",
"dependencies": { "dependencies": {
"is-number": "^7.0.0" "is-number": "^7.0.0"
}, },
+19 -2
View File
@@ -10,10 +10,12 @@
"part1": "GROW YOUR", "part1": "GROW YOUR",
"part2": "BUSINESS" "part2": "BUSINESS"
}, },
"subheading": { "subheading": {
"part1": "We do all the digital footprint for you,", "part1": "We do all the digital footprint for you,",
"part2": "so you can focus on what's important!" "part2": "so you can focus on what's important!"
}, },
"button": "Yes, I want that!" "button": "Yes, I want that!"
}, },
@@ -22,9 +24,12 @@
"part1": "We've got your", "part1": "We've got your",
"part2": "footprint", "part2": "footprint",
"part3": "bullsh", "part3": "bullsh",
"part4": "t covered!" "part4": "*",
"part5": "t covered!"
}, },
"subheading": "Unlock the full potential of your business with our services.", "subheading": "Unlock the full potential of your business with our services.",
"cards": { "cards": {
"marketing": { "marketing": {
"card1": { "card1": {
@@ -44,6 +49,7 @@
"description": "Plan" "description": "Plan"
} }
}, },
"website": { "website": {
"card1": { "card1": {
"title": "Idealize", "title": "Idealize",
@@ -62,6 +68,7 @@
"description": "Website" "description": "Website"
} }
}, },
"social": { "social": {
"card1": { "card1": {
"title": "Analyze", "title": "Analyze",
@@ -80,6 +87,7 @@
"description": "Platforms" "description": "Platforms"
} }
}, },
"media": { "media": {
"card1": { "card1": {
"title": "Envision", "title": "Envision",
@@ -100,31 +108,38 @@
} }
} }
}, },
"results": { "results": {
"heading": { "heading": {
"part1": "Ok... So what makes", "part1": "Ok... So what makes",
"part2": "us different?" "part2": "us different?"
}, },
"subheading": "We have helped many businesses grow and expand their digital footprint.", "subheading": "We have helped many businesses grow and expand their digital footprint.",
"cards": { "cards": {
"card1": { "card1": {
"title": "GARANTEED", "title": "GARANTEED",
"description": "We only win if you win!\nThats the basis for a good\npartnership.\nYou wont carry all the risk,\nwell share it." "description": "We only win if you win!\nThats the basis for a good\npartnership.\nYou wont carry all the risk,\nwell share it."
}, },
"card2": { "card2": {
"title": "RESULTS", "title": "RESULTS",
"description": "Our first priority is to get\nyou results.\n\nLess talk, more walk." "description": "Our first priority is to get\nyou results.\n\nLess talk, more walk."
}, },
"card3": { "card3": {
"title": "LOCAL", "title": "LOCAL",
"description": "Were not a anonymous call\ncenter. Were a local\ncompany, so youll be able to\nreach us when you need us" "description": "Were not a anonymous call\ncenter. Were a local\ncompany, so youll be able to\nreach us when you need us"
}, },
"card4": { "card4": {
"title": "SPECIALIZED", "title": "SPECIALIZED",
"description": "Jack of all trades... master\nof none Specialization\nworks. We work with\nindustries we know, so we\ncan guarantee results." "description": "Jack of all trades... master\nof none. Specialization\nworks. We work with\nindustries we know, so we\ncan guarantee results."
} }
} }
}, },
"contact": { "contact": {
"heading": { "heading": {
"part1": "Contact Us For", "part1": "Contact Us For",
@@ -132,10 +147,12 @@
"part3": "Free", "part3": "Free",
"part4": "Analysis" "part4": "Analysis"
}, },
"subheading": { "subheading": {
"part1": "Would you like to know what we could do for you? Fill out the form ad well get", "part1": "Would you like to know what we could do for you? Fill out the form ad well get",
"part2": "back to you No obligation, no annoying tactics. We wont waste your time." "part2": "back to you No obligation, no annoying tactics. We wont waste your time."
}, },
"form": { "form": {
"name": "Name", "name": "Name",
"email": "Email", "email": "Email",
+153
View File
@@ -0,0 +1,153 @@
{
"navbar": {
"services": "Serviços",
"advantages": "Vantagens",
"contact": "Contacto"
},
"hero": {
"heading": {
"part1": "CRESÇA O",
"part2": "SEU NEGÓCIO"
},
"subheading": {
"part1": "Nós tratamos de toda a sua presença digital,",
"part2": "para que possa concentrar-se no que é importante!"
},
"button": "Eu quero isto!"
},
"services": {
"heading": {
"part1": "Nós cuidamos da sua",
"part2": "presença",
"part3": "digital",
"part4": " ",
"part5": "por completo!"
},
"subheading": "Desbloqueie todo o potencial do seu negócio com os nossos serviços.",
"cards": {
"marketing": {
"card1": {
"title": "Analisar",
"description": "Problema"
},
"card2": {
"title": "Criar",
"description": "Estratégia"
},
"card3": {
"title": "Escalar",
"description": "Empresa"
},
"card4": {
"title": "Executar",
"description": "Plano"
}
},
"website": {
"card1": {
"title": "Idealizar",
"description": "Website"
},
"card2": {
"title": "Design",
"description": "Website"
},
"card3": {
"title": "Desenvolver",
"description": "Website"
},
"card4": {
"title": "Construir",
"description": "Website"
}
},
"social": {
"card1": {
"title": "Analisar",
"description": "Algoritmo"
},
"card2": {
"title": "Agendar",
"description": "Conteúdo"
},
"card3": {
"title": "Segmentar",
"description": "Audiência"
},
"card4": {
"title": "Expandir",
"description": "Plataformas"
}
},
"media": {
"card1": {
"title": "Visualizar",
"description": "Perspectiva"
},
"card2": {
"title": "Capturar",
"description": "Momentos"
},
"card3": {
"title": "Editar",
"description": "Momentos"
},
"card4": {
"title": "Publicar",
"description": "Conteúdo"
}
}
}
},
"results": {
"heading": {
"part1": "Ok... Então o que nos torna",
"part2": "diferentes?"
},
"subheading": "Ajudamos muitos negócios a crescer e expandir a sua presença digital.",
"cards": {
"card1": {
"title": "GARANTIDO",
"description": "Nós só ganhamos se você ganhar!\nEssa é a base para uma boa\nparceria.\nVocê não vai carregar todo o risco,\nnós vamos compartilhá-lo."
},
"card2": {
"title": "RESULTADOS",
"description": "A nossa primeira prioridade é obter\nresultados.\n\nMenos conversa, mais ação."
},
"card3": {
"title": "LOCAL",
"description": "Não somos um centro de chamadas anónimo. Somos uma\nempresa local, por isso poderá\ncontactar-nos quando precisar."
},
"card4": {
"title": "ESPECIALIZADO",
"description": "Faz-tudo... mestre de nada. A especialização\nfunciona. Trabalhamos com\nindústrias que conhecemos, para que possamos\ngarantir resultados."
}
}
},
"contact": {
"heading": {
"part1": "Contacte-nos para uma",
"part2": "Análise",
"part3": "Gratuita",
"part4": ""
},
"subheading": {
"part1": "Gostaria de saber o que podemos fazer por si? Preencha o formulário e nós entraremos",
"part2": "em contacto consigo. Sem obrigações, sem táticas irritantes. Não vamos desperdiçar o seu tempo."
},
"form": {
"name": "Nome",
"email": "Email",
"company": "Empresa",
"phone": "Telefone",
"question": "Qual é a sua pergunta mais importante?",
"message": "Mensagem",
"button": "Enviar"
},
"toasts": {
"success": "A sua mensagem foi enviada com sucesso!",
"error": "Ocorreu um erro ao enviar a sua mensagem. Por favor, tente novamente mais tarde.",
"empty": "Por favor, preencha todos os campos antes de enviar a mensagem."
}
}
}
+2 -2
View File
@@ -19,7 +19,7 @@ const Footer = () => {
> >
<FaLinkedin className="text-gold-light" size={30} /> <FaLinkedin className="text-gold-light" size={30} />
</a> </a>
<a {/* <a
href="https://instagram.com" href="https://instagram.com"
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
@@ -28,7 +28,7 @@ const Footer = () => {
</a> </a>
<a href="https://twitter.com" target="_blank" rel="noopener noreferrer"> <a href="https://twitter.com" target="_blank" rel="noopener noreferrer">
<FaXTwitter className="text-gold-light" size={30} /> <FaXTwitter className="text-gold-light" size={30} />
</a> </a> */}
</div> </div>
<p className="text-center text-gray-400 font-medium"> <p className="text-center text-gray-400 font-medium">
&copy; 2024 LK Results. All rights reservered. &copy; 2024 LK Results. All rights reservered.
+19 -4
View File
@@ -6,7 +6,7 @@ import { useTranslation } from "react-i18next";
export default () => { export default () => {
const [state, setState] = useState(false); const [state, setState] = useState(false);
const { t } = useTranslation(); const { t, i18n } = useTranslation();
const [colorChange, setColorChange] = useState(false); const [colorChange, setColorChange] = useState(false);
const changeColor = () => { const changeColor = () => {
@@ -28,7 +28,16 @@ export default () => {
const handleNavigation = (path: string) => { const handleNavigation = (path: string) => {
const element = document.getElementById(path); const element = document.getElementById(path);
element?.scrollIntoView({ behavior: "smooth" }); const navbarHeight = 110; // Replace with your navbar's height
if (element) {
const top =
element.getBoundingClientRect().top + window.scrollY - navbarHeight;
window.scrollTo({ top: top, behavior: "smooth" });
}
};
const changeLanguage = (lng: string) => {
i18n.changeLanguage(lng);
}; };
return ( return (
@@ -64,7 +73,7 @@ export default () => {
</div> </div>
</div> </div>
<div <div
className={`absolute top-[3.24rem] md:top-0 left-0 w-full z-50 flex flex-col items-center justify-center pb-3 mt-8 md:relative md:bg-transparent md:pb-0 md:mt-0 ${ className={`absolute top-[3.24rem] md:top-0 left-0 w-full z-50 flex flex-col md:flex-row items-center justify-center pb-3 mt-8 md:relative md:bg-transparent md:pb-0 md:mt-0 ${
state state
? colorChange ? colorChange
? "block bg-black bg-opacity-80 transition duration-500" ? "block bg-black bg-opacity-80 transition duration-500"
@@ -72,7 +81,7 @@ export default () => {
: "hidden md:flex" : "hidden md:flex"
}`} }`}
> >
<ul className="text-text-gold space-y-8 md:flex md:space-x-6 md:space-y-0"> <ul className="text-text-gold space-y-8 md:ml-auto md:flex md:space-x-6 md:space-y-0 justify-center items-center">
{navigation.map((item, idx) => { {navigation.map((item, idx) => {
return ( return (
<li key={idx} className="hover:text-white"> <li key={idx} className="hover:text-white">
@@ -91,6 +100,12 @@ export default () => {
); );
})} })}
</ul> </ul>
<button
className="mt-5 md:mt-0 md:ml-auto"
onClick={() => changeLanguage(i18n.language === "en" ? "pt" : "en")}
>
{i18n.language === "en" ? "PT" : "EN"}
</button>
</div> </div>
</div> </div>
</nav> </nav>
+6 -1
View File
@@ -7,7 +7,12 @@ const Hero = () => {
const handleNavigation = (path: string) => { const handleNavigation = (path: string) => {
const element = document.getElementById(path); const element = document.getElementById(path);
element?.scrollIntoView({ behavior: "smooth" }); const navbarHeight = 110; // Replace with your navbar's height
if (element) {
const top =
element.getBoundingClientRect().top + window.scrollY - navbarHeight;
window.scrollTo({ top: top, behavior: "smooth" });
}
}; };
return ( return (
@@ -9,26 +9,30 @@ const CameraCards = () => {
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
<div className="h-full fade-effect flex lg:mt-20 flex-col flex-wrap gap-4 xl:flex-row mx-4"> <div className="h-full flex lg:mt-20 flex-col flex-wrap gap-4 xl:flex-row mx-4">
<Card <Card
title={t("services.cards.media.card1.title")} title={t("services.cards.media.card1.title")}
description={t("services.cards.media.card1.description")} description={t("services.cards.media.card1.description")}
imgSrc={EnvisionImg} imgSrc={EnvisionImg}
delay="0s"
/> />
<Card <Card
title={t("services.cards.media.card2.title")} title={t("services.cards.media.card2.title")}
description={t("services.cards.media.card2.description")} description={t("services.cards.media.card2.description")}
imgSrc={CaptureImg} imgSrc={CaptureImg}
delay="0.2s"
/> />
<Card <Card
title={t("services.cards.media.card3.title")} title={t("services.cards.media.card3.title")}
description={t("services.cards.media.card3.description")} description={t("services.cards.media.card3.description")}
imgSrc={EditImg} imgSrc={EditImg}
delay="0.4s"
/> />
<Card <Card
title={t("services.cards.media.card4.title")} title={t("services.cards.media.card4.title")}
description={t("services.cards.media.card4.description")} description={t("services.cards.media.card4.description")}
imgSrc={PublishImg} imgSrc={PublishImg}
delay="0.6s"
/> />
</div> </div>
); );
@@ -9,26 +9,30 @@ const MarketingCards = () => {
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
<div className="h-full fade-effect flex lg:mt-20 flex-col flex-wrap gap-4 xl:flex-row mx-4"> <div className="h-full flex lg:mt-20 flex-col flex-wrap gap-4 xl:flex-row mx-4">
<Card <Card
title={t("services.cards.marketing.card1.title")} title={t("services.cards.marketing.card1.title")}
description={t("services.cards.marketing.card1.description")} description={t("services.cards.marketing.card1.description")}
imgSrc={AnaliseImg} imgSrc={AnaliseImg}
delay="0s"
/> />
<Card <Card
title={t("services.cards.marketing.card2.title")} title={t("services.cards.marketing.card2.title")}
description={t("services.cards.marketing.card2.description")} description={t("services.cards.marketing.card2.description")}
imgSrc={CreateImg} imgSrc={CreateImg}
delay="0.2s"
/> />
<Card <Card
title={t("services.cards.marketing.card3.title")} title={t("services.cards.marketing.card3.title")}
description={t("services.cards.marketing.card3.description")} description={t("services.cards.marketing.card3.description")}
imgSrc={ScaleImg} imgSrc={ScaleImg}
delay="0.4s"
/> />
<Card <Card
title={t("services.cards.marketing.card4.title")} title={t("services.cards.marketing.card4.title")}
description={t("services.cards.marketing.card4.description")} description={t("services.cards.marketing.card4.description")}
imgSrc={ExecuteImg} imgSrc={ExecuteImg}
delay="0.6s"
/> />
</div> </div>
); );
@@ -2,13 +2,18 @@ interface IProps {
title: string; title: string;
description: string; description: string;
imgSrc: string; imgSrc: string;
delay: string;
} }
const Card = ({ title, description, imgSrc }: IProps) => { const Card = ({ title, description, imgSrc, delay }: IProps) => {
return ( return (
<div <div
className="flex flex-col justify-end flex-1 h-full border-solid border shadow-lg bg-cover bg-center text-center" className="flex flex-col justify-end flex-1 h-full border-solid border shadow-lg bg-cover bg-center text-center"
style={{ backgroundImage: `url(${imgSrc})` }} style={{
backgroundImage: `url(${imgSrc})`,
animation: `fadeEffect 1s ${delay} forwards`,
opacity: 0, // Add this line
}}
> >
<div className="lg:my-6"> <div className="lg:my-6">
<h2 <h2
+2 -2
View File
@@ -20,8 +20,8 @@ const Services = () => {
</h1> </h1>
<h1> <h1>
{t("services.heading.part3")} {t("services.heading.part3")}
<span className="gold-text">*</span> <span className="gold-text">{t("services.heading.part4")}</span>
{t("services.heading.part4")} {t("services.heading.part5")}
</h1> </h1>
<h2 className="sub-header-text">{t("services.subheading")}</h2> <h2 className="sub-header-text">{t("services.subheading")}</h2>
@@ -9,26 +9,30 @@ const SocialMediaCards = () => {
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
<div className="h-full fade-effect flex lg:mt-20 flex-col flex-wrap gap-4 xl:flex-row mx-4"> <div className="h-full flex lg:mt-20 flex-col flex-wrap gap-4 xl:flex-row mx-4">
<Card <Card
title={t("services.cards.social.card1.title")} title={t("services.cards.social.card1.title")}
description={t("services.cards.social.card1.description")} description={t("services.cards.social.card1.description")}
imgSrc={AlgorithmImg} imgSrc={AlgorithmImg}
delay="0s"
/> />
<Card <Card
title={t("services.cards.social.card2.title")} title={t("services.cards.social.card2.title")}
description={t("services.cards.social.card2.description")} description={t("services.cards.social.card2.description")}
imgSrc={ScheduleImg} imgSrc={ScheduleImg}
delay="0.2s"
/> />
<Card <Card
title={t("services.cards.social.card3.title")} title={t("services.cards.social.card3.title")}
description={t("services.cards.social.card3.description")} description={t("services.cards.social.card3.description")}
imgSrc={TargetImg} imgSrc={TargetImg}
delay="0.4s"
/> />
<Card <Card
title={t("services.cards.social.card4.title")} title={t("services.cards.social.card4.title")}
description={t("services.cards.social.card4.description")} description={t("services.cards.social.card4.description")}
imgSrc={ExpandImg} imgSrc={ExpandImg}
delay="0.6s"
/> />
</div> </div>
); );
@@ -9,26 +9,30 @@ const WesiteCards = () => {
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
<div className="h-full fade-effect flex lg:mt-20 flex-col flex-wrap gap-4 xl:flex-row mx-4"> <div className="h-full flex lg:mt-20 flex-col flex-wrap gap-4 xl:flex-row mx-4">
<Card <Card
title={t("services.cards.website.card1.title")} title={t("services.cards.website.card1.title")}
description={t("services.cards.website.card1.description")} description={t("services.cards.website.card1.description")}
imgSrc={IdealizeImg} imgSrc={IdealizeImg}
delay="0s"
/> />
<Card <Card
title={t("services.cards.website.card2.title")} title={t("services.cards.website.card2.title")}
description={t("services.cards.website.card2.description")} description={t("services.cards.website.card2.description")}
imgSrc={DesignImg} imgSrc={DesignImg}
delay="0.2s"
/> />
<Card <Card
title={t("services.cards.website.card3.title")} title={t("services.cards.website.card3.title")}
description={t("services.cards.website.card3.description")} description={t("services.cards.website.card3.description")}
imgSrc={CodeImg} imgSrc={CodeImg}
delay="0.4s"
/> />
<Card <Card
title={t("services.cards.website.card4.title")} title={t("services.cards.website.card4.title")}
description={t("services.cards.website.card4.description")} description={t("services.cards.website.card4.description")}
imgSrc={BuildImg} imgSrc={BuildImg}
delay="0.6s"
/> />
</div> </div>
); );