Skip to content

Commit 59201fa

Browse files
committed
👨‍💻 Fixed the cv download multilanguage
1 parent 29104bb commit 59201fa

File tree

6 files changed

+163
-11
lines changed

6 files changed

+163
-11
lines changed

public/iheb_elazheri_cv_en.pdf

97.1 KB
Binary file not shown.
Binary file not shown.
Lines changed: 139 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,150 @@
11
import { Button } from "flowbite-react";
22
import { useTranslation } from "react-i18next";
3+
import { useState } from "react";
34

45
const DownloadResumeButton = () => {
5-
const resumeLink = "/elazheri_iheb_resume.pdf";
66
const { t } = useTranslation();
7+
const [isOpen, setIsOpen] = useState(false);
8+
const [isDownloading, setIsDownloading] = useState(null);
9+
10+
const languageOptions = [
11+
{
12+
code: 'fr',
13+
label: t('downloadResume.french'),
14+
flag: '🇫🇷',
15+
filename: '/iheb_elazheri_cv_fr.pdf'
16+
},
17+
{
18+
code: 'en',
19+
label: t('downloadResume.english'),
20+
flag: '🇺🇸',
21+
filename: '/iheb_elazheri_cv_en.pdf'
22+
}
23+
];
24+
25+
const handleDownload = async (option) => {
26+
setIsDownloading(option.code);
27+
28+
// Create download link
29+
const link = document.createElement('a');
30+
link.href = option.filename;
31+
link.download = `Elazheri_Iheb_CV_${option.code.toUpperCase()}.pdf`;
32+
document.body.appendChild(link);
33+
link.click();
34+
document.body.removeChild(link);
35+
36+
// Reset states
37+
setTimeout(() => {
38+
setIsDownloading(null);
39+
setIsOpen(false);
40+
}, 1000);
41+
};
742

843
return (
9-
<div className="flex items-center justify-center mr-20">
10-
<a href={resumeLink} download="Elazheri Iheb CV.pdf">
11-
<Button
12-
gradientDuoTone="cyanToBlue"
13-
className="px-6 py-1 rounded-lg shadow-md transition-transform transform hover:scale-105 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-cyan-600 text-color-black "
14-
>
15-
{t("navbar.cv")}
16-
</Button>
17-
</a>
44+
<div className="relative flex items-center justify-center mr-20">
45+
{/* Main Download Button */}
46+
<Button
47+
onClick={() => setIsOpen(!isOpen)}
48+
gradientDuoTone="cyanToBlue"
49+
className="px-6 py-1 rounded-lg shadow-md transition-all duration-300 transform hover:scale-105 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-cyan-600 text-color-black relative"
50+
>
51+
<span className="flex items-center gap-2">
52+
📄 {t("navbar.cv")}
53+
<svg
54+
className={`w-4 h-4 transition-transform duration-300 ${isOpen ? 'rotate-180' : ''}`}
55+
fill="none"
56+
stroke="currentColor"
57+
viewBox="0 0 24 24"
58+
>
59+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
60+
</svg>
61+
</span>
62+
</Button>
63+
64+
{/* Dropdown Menu */}
65+
{isOpen && (
66+
<div className="absolute top-full mt-2 bg-white dark:bg-gray-800 rounded-xl shadow-2xl border border-gray-200 dark:border-gray-700 min-w-[280px] z-50 animate-fadeIn">
67+
{/* Header */}
68+
<div className="p-4 border-b border-gray-200 dark:border-gray-700">
69+
<h3 className="font-semibold text-gray-900 dark:text-white text-sm">
70+
{t('downloadResume.selectLanguage')}
71+
</h3>
72+
<p className="text-xs text-gray-500 dark:text-gray-400 mt-1">
73+
{t('downloadResume.chooseVersion')}
74+
</p>
75+
</div>
76+
77+
{/* Language Options */}
78+
<div className="p-2">
79+
{languageOptions.map((option) => (
80+
<button
81+
key={option.code}
82+
onClick={() => handleDownload(option)}
83+
disabled={isDownloading}
84+
className="w-full flex items-center gap-3 p-3 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-all duration-200 group disabled:opacity-50 disabled:cursor-not-allowed"
85+
>
86+
<span className="text-2xl">{option.flag}</span>
87+
<div className="flex-1 text-left">
88+
<div className="font-medium text-gray-900 dark:text-white text-sm">
89+
{option.label}
90+
</div>
91+
<div className="text-xs text-gray-500 dark:text-gray-400">
92+
{t('downloadResume.fileFormat')}
93+
</div>
94+
</div>
95+
96+
{/* Download Icon or Loading */}
97+
<div className="flex items-center">
98+
{isDownloading === option.code ? (
99+
<div className="flex items-center gap-2">
100+
<div className="animate-spin rounded-full h-4 w-4 border-b-2 border-cyan-600"></div>
101+
<span className="text-xs text-cyan-600 font-medium">
102+
{t('downloadResume.downloading')}
103+
</span>
104+
</div>
105+
) : (
106+
<svg
107+
className="w-5 h-5 text-gray-400 group-hover:text-cyan-600 transition-colors"
108+
fill="none"
109+
stroke="currentColor"
110+
viewBox="0 0 24 24"
111+
>
112+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
113+
</svg>
114+
)}
115+
</div>
116+
</button>
117+
))}
118+
</div>
119+
</div>
120+
)}
121+
122+
{/* Backdrop to close dropdown */}
123+
{isOpen && (
124+
<div
125+
className="fixed inset-0 z-40"
126+
onClick={() => setIsOpen(false)}
127+
/>
128+
)}
129+
130+
{/* Custom CSS for animations */}
131+
<style jsx>{`
132+
@keyframes fadeIn {
133+
from {
134+
opacity: 0;
135+
transform: translateY(-10px);
136+
}
137+
to {
138+
opacity: 1;
139+
transform: translateY(0);
140+
}
141+
}
142+
.animate-fadeIn {
143+
animation: fadeIn 0.2s ease-out;
144+
}
145+
`}</style>
18146
</div>
19147
);
20148
};
21149

22-
export default DownloadResumeButton;
150+
export default DownloadResumeButton;

src/locales/ar/translation.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,5 +203,13 @@
203203
"title": "قم بإعطاء هذا المشروع نجمة!",
204204
"description": "تم التصميم والتطوير بواسطة إيهاب الأزهري",
205205
"rights": "جميع الآراء والأعمال خاصة بي"
206+
},
207+
"downloadResume": {
208+
"selectLanguage": "اختر اللغة",
209+
"chooseVersion": "اختر النسخة المفضلة من سيرتك الذاتية",
210+
"french": "النسخة الفرنسية",
211+
"english": "النسخة الإنجليزية",
212+
"downloading": "جاري التحميل...",
213+
"fileFormat": "تنسيق PDF • جودة عالية"
206214
}
207215
}

src/locales/en/translation.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,5 +203,13 @@
203203
"title": "Give this project a star!",
204204
"description": "Designed and built by Elazheri Iheb",
205205
"rights": "All views and work are my own"
206+
},
207+
"downloadResume": {
208+
"selectLanguage": "Select Language",
209+
"chooseVersion": "Choose your preferred CV version",
210+
"french": "French Version",
211+
"english": "English Version",
212+
"downloading": "Downloading...",
213+
"fileFormat": "PDF Format • High Quality"
206214
}
207215
}

src/locales/fr/translation.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,5 +203,13 @@
203203
"title": "Donnez une étoile à ce projet !",
204204
"description": "Conçu et développé par Elazheri Iheb",
205205
"rights": "Tous les points de vue et le travail sont les miens"
206+
},
207+
"downloadResume": {
208+
"selectLanguage": "Sélectionner la langue",
209+
"chooseVersion": "Choisissez votre version de CV préférée",
210+
"french": "Version Française",
211+
"english": "Version Anglaise",
212+
"downloading": "Téléchargement...",
213+
"fileFormat": "Format PDF • Haute Qualité"
206214
}
207215
}

0 commit comments

Comments
 (0)