Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Multilingual Translator #193

Merged
merged 12 commits into from
Oct 12, 2024
Merged
Binary file added frontend/src/assets/img/google.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
107 changes: 107 additions & 0 deletions frontend/src/components/Shared/GoogleTranslate.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import React, { useEffect } from "react";

const GoogleTranslate = () => {
useEffect(() => {
window.googleTranslateInit = () => {
if (!window.google?.translate?.TranslateElement) {
setTimeout(window.googleTranslateInit, 100);
} else {
new window.google.translate.TranslateElement({
pageLanguage: 'en',
includedLanguages: 'en,hi,pa,sa,mr,ur,bn,es,ja,ko,zh-CN,es,nl,fr,de,it,ta,te',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Remove duplicate language code 'es' in includedLanguages

The language code 'es' for Spanish is included twice in the includedLanguages string. This duplication is unnecessary and can be removed to prevent any potential issues.

Apply this diff to remove the duplicate:

           includedLanguages: 'en,hi,pa,sa,mr,ur,bn,es,ja,ko,zh-CN,es,nl,fr,de,it,ta,te',
-          includedLanguages: 'en,hi,pa,sa,mr,ur,bn,es,ja,ko,zh-CN,es,nl,fr,de,it,ta,te',
+          includedLanguages: 'en,hi,pa,sa,mr,ur,bn,es,ja,ko,zh-CN,nl,fr,de,it,ta,te',
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
includedLanguages: 'en,hi,pa,sa,mr,ur,bn,es,ja,ko,zh-CN,es,nl,fr,de,it,ta,te',
includedLanguages: 'en,hi,pa,sa,mr,ur,bn,es,ja,ko,zh-CN,nl,fr,de,it,ta,te',

layout: window.google.translate.TranslateElement.InlineLayout.HORIZONTAL,
defaultLanguage: 'en',
autoDisplay: false,
}, 'google_element');
}
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Prevent potential infinite retries in googleTranslateInit function

The googleTranslateInit function retries initialization every 100ms if window.google.translate.TranslateElement is not available. If the TranslateElement never becomes available (e.g., due to network issues or script loading failure), this could result in infinite retries, potentially impacting performance.

Consider adding a retry limit or a timeout to prevent infinite retries. Here's how you might implement a retry limit:

+      let retryCount = 0;
+      const maxRetries = 50; // Adjust as needed

       window.googleTranslateInit = () => {
         if (!window.google?.translate?.TranslateElement) {
+          if (retryCount < maxRetries) {
+            retryCount++;
             setTimeout(window.googleTranslateInit, 100);
+          } else {
+            console.error('Failed to initialize Google Translate after maximum retries.');
+          }
         } else {
           new window.google.translate.TranslateElement({
             pageLanguage: 'en',

Alternatively, you could implement a timeout mechanism:

+      const startTime = Date.now();
+      const timeout = 5000; // Timeout after 5 seconds

       window.googleTranslateInit = () => {
         if (!window.google?.translate?.TranslateElement) {
+          if (Date.now() - startTime < timeout) {
             setTimeout(window.googleTranslateInit, 100);
+          } else {
+            console.error('Failed to initialize Google Translate within the timeout period.');
+          }
         } else {
           new window.google.translate.TranslateElement({
             pageLanguage: 'en',

Committable suggestion was skipped due to low confidence.


const loadGoogleTranslateScript = () => {
if (!document.getElementById("google_translate_script")) {
const script = document.createElement("script");
script.type = "text/javascript";
script.src = "https://translate.google.com/translate_a/element.js?cb=googleTranslateInit";
script.id = "google_translate_script";
script.onerror = () => console.error('Error loading Google Translate script');
document.body.appendChild(script);
}
};

loadGoogleTranslateScript();

if (window.google && window.google.translate) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Simplify condition using optional chaining

You can simplify the condition by using optional chaining, which enhances readability by concisely checking for the existence of window.google and window.google.translate.

Apply this diff to simplify the condition:

-     if (window.google && window.google.translate) {
+     if (window.google?.translate) {
        window.googleTranslateInit();
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (window.google && window.google.translate) {
if (window.google?.translate) {
🧰 Tools
🪛 Biome

[error] 32-32: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

window.googleTranslateInit();
}

return () => {
// Cleanup logic if necessary
};
}, []);

return (
<div id="google_element" className="google-translate-container pl-20 md:pl-0">
<style jsx>{`
.goog-te-combo {
display: inline-block;
background-color: #e0f2ff; /* Light blue background */
border: 2px solid #0056b3; /* Dark blue border */
border-radius: 0.5rem; /* Slightly more rounded */
padding: 0.5rem 1rem; /* Tailwind: p-2 */
font-size: 0.875rem; /* Tailwind: text-sm */
transition: all 0.3s ease; /* Smooth transition */
outline: none;
color: #000; /* Black text */
font-weight: 500; /* Tailwind: font-medium */
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.2); /* Slight shadow */
}
.goog-te-combo:hover {
background-color: #b3e0ff; /* Lighter blue on hover */
border-color: #004494; /* Darker blue on hover */
box-shadow: 0 6px 8px rgba(0, 0, 0, 0.25); /* Stronger shadow on hover */
}
.goog-logo-link {
display: none !important;
}
.goog-te-gadget {
color: transparent !important;
}
.goog-te-gadget > span > a {
display: none !important;
}
.goog-te-gadget .goog-te-combo {
color: #0056b3 !important; /* Dark blue text */
}
#google_translate_element .goog-te-gadget-simple .goog-te-menu-value span:first-child {
display: none;
}
#google_translate_element .goog-te-gadget-simple .goog-te-menu-value:before {
content: 'Translate'; /* Change the default text */
color: #0056b3; /* Dark blue text */
}
.goog-te-banner-frame {
display: none !important;
}
.goog-te-menu-frame {
max-height: 400px !important;
overflow-y: auto !important;
background-color: #fff; /* White background for dropdown */
border: 1px solid #cce5ff; /* Light blue border */
border-radius: 0.5rem; /* Slightly more rounded */
}
/* Hide the banner frame */
.goog-te-banner-frame {
display: none !important;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Remove duplicated styles.

The style for hiding the banner frame is duplicated. Consider removing this duplicate to keep the styles DRY (Don't Repeat Yourself).

Remove these lines as they are already defined earlier:

-        /* Hide the banner frame */
-        .goog-te-banner-frame {
-          display: none !important;
-        }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
.goog-te-banner-frame {
display: none !important;
}

/* Customize the iframe */
.skiptranslate > iframe {
height: 0 !important;
border-style: none;
box-shadow: none;
}
`}
</style>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider moving inline styles to a separate CSS file.

While the inline styles effectively customize the Google Translate widget, moving them to a separate CSS file would improve maintainability and reusability. This separation of concerns aligns with best practices in React development.

</div>
);
};

export default GoogleTranslate;
29 changes: 18 additions & 11 deletions frontend/src/components/Shared/footer/Content.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useEffect, useState } from "react";
import Logo from "../../../assets/Logo/playcafe.png";
import { FaFacebook, FaInstagram, FaTiktok } from "react-icons/fa";
import GoogleTranslate from "../GoogleTranslate";

export default function Content() {
return (
Expand Down Expand Up @@ -35,21 +36,18 @@ const Section2 = () => {
</div>
)}
<div
className={`flex ${
isWide ? "justify-between items-end" : "flex-col items-center"
} text-white`}
className={`flex ${isWide ? "justify-between items-end" : "flex-col items-center"
} text-white`}
>
<h1
className={`${
isWide ? "text-[9vw]" : "text-[12vw] mt-10"
} leading-[0.8]`}
className={`${isWide ? "text-[9vw]" : "text-[12vw] mt-10"
} leading-[0.8]`}
>
BoardGame {!isWide && <br />}
</h1>
<h1
className={`${
isWide ? "text-[9vw]" : "text-[12vw] mt-4"
} leading-[0.8]`}
className={`${isWide ? "text-[9vw]" : "text-[12vw] mt-4"
} leading-[0.8]`}
>
Cafe
</h1>
Expand Down Expand Up @@ -85,7 +83,7 @@ const Nav = () => {
];
const socialLink = [
{ name: "Facebook", link: "https://www.facebook.com/sipnplaynyc/", icon: <FaFacebook /> },
{ name: "Instagram", link: "https://www.instagram.com/sipnplaynyc/?hl=en", icon: <FaInstagram />},
{ name: "Instagram", link: "https://www.instagram.com/sipnplaynyc/?hl=en", icon: <FaInstagram /> },
{
name: "Tiktok",
link: "https://www.tiktok.com/@sipnplaynycofficial?lang=en", icon: <FaTiktok />
Expand Down Expand Up @@ -115,7 +113,7 @@ const Nav = () => {
className="hover:text-white duration-300 flex items-center gap-2"
key={index}
href={item.link}
aria-label={`${item.name} - opens in a new tab`}
aria-label={`${item.name} - opens in a new tab`}
>
{item.icon}
{item.name}
Expand All @@ -133,6 +131,15 @@ const Nav = () => {
<a href="tel:+17189711684" className="mb-2 hover:underline">
718-971-1684
</a>

<div className="flex items-center justify-center mt-4">
<img
src="https://w7.pngwing.com/pngs/211/630/png-transparent-google-translate-translation-android-noodle-blue-english-text.png"
alt="Google Translate"
className="w-12 h-12"
/>
<GoogleTranslate/>
</div>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Issues Found: Review of Google Translate integration implementation

  1. The image source still uses an external URL. Consider using a local asset to mitigate potential security risks and improve load performance.

  2. The GoogleTranslate component relies on an external script from Google Translate. Ensure that this dependency is necessary and assess any security implications it may introduce.

  3. The placement of the translation feature within the "Contact Us" section may hinder user accessibility. Consider relocating it to a more prominent area, such as the header or a persistent floating button, to enhance visibility and usability.

🔗 Analysis chain

Review needed: Google Translate integration implementation

The addition of the Google Translate UI elements aligns with the PR objective. However, there are a few points to consider:

  1. The image source uses an external URL. Consider using a local asset instead to avoid potential security risks and improve performance.

  2. The GoogleTranslate component is rendered, but its implementation is not visible in this file. Could you provide more information about how this component works and handles the translation functionality?

  3. The placement of the translation feature within the "Contact Us" section of the footer may not be ideal for user accessibility. Consider moving it to a more prominent location, such as the header or a floating button, to make it easily discoverable for users.

To ensure the GoogleTranslate component is properly implemented, please run the following script:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the implementation of the GoogleTranslate component

# Test: Check if the GoogleTranslate component file exists
fd --type f --full-path "GoogleTranslate.(js|jsx|ts|tsx)" src

# Test: Examine the content of the GoogleTranslate component
fd --type f --full-path "GoogleTranslate.(js|jsx|ts|tsx)" src --exec cat {}

# Test: Check for any Google Translate API usage
rg --type js "translate\.google\.com" src

Length of output: 413


Script:

#!/bin/bash
# Description: Verify the implementation of the GoogleTranslate component without assuming a 'src' directory

# Test: Check if the GoogleTranslate component file exists anywhere in the repository
fd --type f --full-path "GoogleTranslate.(js|jsx|ts|tsx)" .

# Test: Examine the content of the GoogleTranslate component if it exists
fd --type f --full-path "GoogleTranslate.(js|jsx|ts|tsx)" . --exec cat {}

# Test: Check for any Google Translate API usage across the repository
rg --type js "translate\.google\.com" .

Length of output: 4118

</div>
</div>
);
Expand Down
Loading