feat: update footer and navbar links, enhance button styles, and improve calendar layout
This commit is contained in:
@@ -1,25 +1,23 @@
|
|||||||
import { Link } from 'react-router-dom';
|
|
||||||
import { FaInstagram, FaLinkedin, FaRegEnvelope } from "react-icons/fa";
|
import { FaInstagram, FaLinkedin, FaRegEnvelope } from "react-icons/fa";
|
||||||
import logoHumic from "../assets/logo.png";
|
import logoHumic from "../assets/logo.png";
|
||||||
|
|
||||||
const internshipLinks = [
|
const internshipLinks = [
|
||||||
{ label: "Beranda", path: "/" },
|
{ label: "Beranda", path: "/" },
|
||||||
{ label: "Tentang", path: "/about-us" },
|
{ label: "Tentang", path: "/about-us" },
|
||||||
{ label: "Life At Humic", path: "" },
|
{ label: "Life At Humic", path: "/internships" },
|
||||||
{ label: "Our Developer", path: "/our-developer" }
|
{ label: "Our Developer", path: "/our-developer" }
|
||||||
];
|
];
|
||||||
|
|
||||||
const externalLinks = [
|
const externalLinks = [
|
||||||
{ label: "Humic Website", href: "https://humic.telkomuniversity.ac.id/" },
|
{ label: "Humic Website", href: "https://humic.telkomuniversity.ac.id/" },
|
||||||
{ label: "Our Activity", href: "https://humic.telkomuniversity.ac.id/humicinmedia/" },
|
{ label: "Our Activity", href: "https://humic.telkomuniversity.ac.id/humicinmedia/" },
|
||||||
{ label: "Life At Humic", href: "" },
|
{ label: "Life At Humic", href: "https://humic.telkomuniversity.ac.id/" },
|
||||||
// { label: "Our Developer", href: "#" },
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const socials = [
|
const socials = [
|
||||||
{ label: "Instagram", icon: FaInstagram, href: "https://www.instagram.com/humicengineering/" },
|
{ label: "Instagram", icon: FaInstagram, href: "https://www.instagram.com/humicengineering/" },
|
||||||
{ label: "LinkedIn", icon: FaLinkedin, href: "https://www.linkedin.com/company/humic-engineering/" },
|
{ label: "LinkedIn", icon: FaLinkedin, href: "https://www.linkedin.com/company/humic-engineering/" },
|
||||||
{ label: "Email", icon: FaRegEnvelope, href: "" },
|
{ label: "Email", icon: FaRegEnvelope, href: "mailto:humic@telkomuniversity.ac.id" },
|
||||||
];
|
];
|
||||||
|
|
||||||
export function FooterIntern() {
|
export function FooterIntern() {
|
||||||
@@ -45,7 +43,7 @@ export function FooterIntern() {
|
|||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
aria-label={label}
|
aria-label={label}
|
||||||
className="w-10 h-10 border rounded-full bg-gray-100 flex items-center justify-center text-gray-600 hover:bg-red-50 hover:text-red-600 transition-colors"
|
className="w-10 h-10 border rounded-full bg-gray-100 flex items-center justify-center text-gray-600 hover:bg-red-50 hover:text-red-800 transition-colors"
|
||||||
>
|
>
|
||||||
<Icon className="w-4 h-4" />
|
<Icon className="w-4 h-4" />
|
||||||
</a>
|
</a>
|
||||||
@@ -60,12 +58,14 @@ export function FooterIntern() {
|
|||||||
<ul className="flex flex-col gap-0.5 font-semibold">
|
<ul className="flex flex-col gap-0.5 font-semibold">
|
||||||
{internshipLinks.map(({ label, path }) => (
|
{internshipLinks.map(({ label, path }) => (
|
||||||
<li key={label}>
|
<li key={label}>
|
||||||
<Link
|
<a
|
||||||
to={path}
|
href={path}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
className="text-[12.5px] text-gray-600 hover:text-red-800 transition-colors"
|
className="text-[12.5px] text-gray-600 hover:text-red-800 transition-colors"
|
||||||
>
|
>
|
||||||
{label}
|
{label}
|
||||||
</Link>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@@ -59,19 +59,19 @@ const Navbar = () => {
|
|||||||
<div className="hidden md:flex items-center gap-8 text-[18px] font-semibold">
|
<div className="hidden md:flex items-center gap-8 text-[18px] font-semibold">
|
||||||
<button
|
<button
|
||||||
onClick={() => navigate("/about-us")}
|
onClick={() => navigate("/about-us")}
|
||||||
className="hover:text-gray-600 transition cursor-pointer"
|
className="hover:text-blue-600 transition cursor-pointer"
|
||||||
>
|
>
|
||||||
About Us
|
About Us
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={handleContactClick}
|
onClick={handleContactClick}
|
||||||
className="hover:text-gray-600 transition cursor-pointer"
|
className="hover:text-blue-600 transition cursor-pointer"
|
||||||
>
|
>
|
||||||
Contact Us
|
Contact Us
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={() => navigate("/internships")}
|
onClick={() => navigate("/internships")}
|
||||||
className="hover:text-gray-600 transition cursor-pointer"
|
className="hover:text-grblueay-600 transition cursor-pointer"
|
||||||
>
|
>
|
||||||
Internship
|
Internship
|
||||||
</button>
|
</button>
|
||||||
@@ -80,7 +80,7 @@ const Navbar = () => {
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
navigate("/login-internify");
|
navigate("/login-internify");
|
||||||
}}
|
}}
|
||||||
className="hover:text-red-600 transition cursor-pointer"
|
className="hover:text-blue-600 transition cursor-pointer"
|
||||||
>
|
>
|
||||||
Portal LMS
|
Portal LMS
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -103,11 +103,13 @@ export default function HomeCalendar() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="box">
|
<div className="box">
|
||||||
|
<div className="flex flex-col py-4">
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
<div className="flex items-center justify-between mb-4 px-6">
|
<div className="flex items-center justify-between mb-4 px-13">
|
||||||
<h2 className="font-bold text-font">
|
<h2 className="font-bold text-font">
|
||||||
{MONTH_NAMES[currentMonth]} {currentYear}
|
{MONTH_NAMES[currentMonth]} {currentYear}
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<button
|
<button
|
||||||
onClick={prevMonth}
|
onClick={prevMonth}
|
||||||
@@ -116,6 +118,7 @@ export default function HomeCalendar() {
|
|||||||
>
|
>
|
||||||
<ChevronLeft className="w-4 h-4 text-gray-500" />
|
<ChevronLeft className="w-4 h-4 text-gray-500" />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
onClick={nextMonth}
|
onClick={nextMonth}
|
||||||
className="p-1 rounded hover:bg-gray-100 transition-colors"
|
className="p-1 rounded hover:bg-gray-100 transition-colors"
|
||||||
@@ -126,34 +129,46 @@ export default function HomeCalendar() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid grid-cols-7 mb-1 px-5">
|
<div className="grid grid-cols-7 mb-1 px-10 md:px-0">
|
||||||
{DAY_LABELS.map(day => (
|
{DAY_LABELS.map((day) => (
|
||||||
<div key={day} className="text-center text-xs text-gray-400 font-medium py-1">
|
<div
|
||||||
|
key={day}
|
||||||
|
className="text-center text-xs text-gray-400 font-medium py-1"
|
||||||
|
>
|
||||||
{day}
|
{day}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid grid-cols-7 px-5">
|
<div className="grid grid-cols-7 px-10 md:px-0">
|
||||||
{/* Trailing days from prev month */}
|
{/* Trailing days from previous month */}
|
||||||
{trailingDays.map(day => (
|
{trailingDays.map((day) => (
|
||||||
<div key={`prev-${day}`} className="text-center py-2">
|
<div key={`prev-${day}`} className="text-center py-2">
|
||||||
<span className="text-xs text-gray-300">{day}</span>
|
<span className="text-xs text-gray-400">{day}</span>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
{currentDays.map(day => (
|
{currentDays.map((day) => (
|
||||||
<div key={day} className="flex justify-center items-center py-1">
|
<div
|
||||||
|
key={day}
|
||||||
|
className="flex justify-center items-center py-1"
|
||||||
|
>
|
||||||
<div className="w-7 flex items-center justify-center">
|
<div className="w-7 flex items-center justify-center">
|
||||||
{isToday(day) ? (
|
{isToday(day) ? (
|
||||||
<span className="w-8 h-7 flex items-center justify-center border-b-2 text-xs font-semibold">
|
<span className="w-8 h-7 flex items-center justify-center text-red border-b-2 border-red text-xs font-semibold">
|
||||||
{day}
|
{day}
|
||||||
</span>
|
</span>
|
||||||
) : (
|
) : (
|
||||||
<span
|
<span
|
||||||
className={`w-full h-7 flex items-center justify-center text-xs
|
className={`w-full h-7 flex items-center justify-center text-xs
|
||||||
${isBold(day) ? 'font-bold text-gray-800' : 'text-gray-700'}
|
${isBold(day)
|
||||||
${hasDeadline(day) ? 'bg-red text-white rounded-full' : ''}
|
? "font-bold text-gray-800"
|
||||||
|
: "text-gray-700"
|
||||||
|
}
|
||||||
|
${hasDeadline(day)
|
||||||
|
? "bg-red text-white rounded-full"
|
||||||
|
: ""
|
||||||
|
}
|
||||||
transition-colors`}
|
transition-colors`}
|
||||||
>
|
>
|
||||||
{day}
|
{day}
|
||||||
@@ -164,34 +179,40 @@ export default function HomeCalendar() {
|
|||||||
))}
|
))}
|
||||||
|
|
||||||
{/* Leading days from next month */}
|
{/* Leading days from next month */}
|
||||||
{leadingDays.map(day => (
|
{leadingDays.map((day) => (
|
||||||
<div key={`next-${day}`} className="text-center py-2">
|
<div key={`next-${day}`} className="text-center py-2">
|
||||||
<span className="text-xs text-gray-300">{day}</span>
|
<span className="text-xs text-gray-400">{day}</span>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Divider */}
|
{/* Divider */}
|
||||||
<hr className="my-3 border-box-border" />
|
<hr className="my-1.5 border-box-border" />
|
||||||
|
|
||||||
{/* Upcoming Deadlines */}
|
{/* Upcoming Deadlines */}
|
||||||
<div className='px-5 mt-2'>
|
<div className="px-8 mt-2">
|
||||||
<p className="text-[10px] font-semibold text-font uppercase tracking-widest mb-2">
|
<p className="text-[10px] font-semibold text-font uppercase tracking-widest mb-2">
|
||||||
Upcoming Deadlines
|
Upcoming Deadlines
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
{upcomingDeadlines.length > 0 ? (
|
{upcomingDeadlines.length > 0 ? (
|
||||||
<ul className="flex flex-col gap-1">
|
<ul className="flex flex-col gap-1">
|
||||||
{upcomingDeadlines.map((d, i) => (
|
{upcomingDeadlines.map((d, i) => (
|
||||||
<li key={i} className="flex items-center gap-2">
|
<li key={i} className="flex items-center gap-2">
|
||||||
<span className="w-2 h-2 rounded-full bg-red flex-shrink-0" />
|
<span className="w-2 h-2 rounded-full bg-red flex-shrink-0" />
|
||||||
<span className="text-xs text-font-shade">{formatDate(d.date)} - {d.label}</span>
|
<span className="text-xs text-font-shade">
|
||||||
|
{formatDate(d.date)} - {d.label}
|
||||||
|
</span>
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
) : (
|
) : (
|
||||||
<p className="text-[11px] text-font-shade">No upcoming deadlines this month.</p>
|
<p className="text-[11px] text-font-shade">
|
||||||
|
No upcoming deadlines this month.
|
||||||
|
</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
@@ -151,7 +151,7 @@ export default function CertificateAvailable({ project, certificate, templateUrl
|
|||||||
<button
|
<button
|
||||||
onClick={handleDownloadPdf}
|
onClick={handleDownloadPdf}
|
||||||
disabled={downloadingPdf}
|
disabled={downloadingPdf}
|
||||||
className="flex items-center justify-center gap-2 w-full bg-red-700 hover:bg-red-800 active:scale-95 transition-all text-white font-semibold py-2 rounded-xl text-sm"
|
className="flex items-center justify-center gap-2 w-full bg-red-700 hover:bg-red-800 active:scale-95 transition-all text-white font-semibold py-2 rounded-xl text-sm hover:cursor-pointer"
|
||||||
>
|
>
|
||||||
<Download className="w-4 h-4" />
|
<Download className="w-4 h-4" />
|
||||||
{downloadingPdf ? "Memproses" : "Unduh Sertifikat"}
|
{downloadingPdf ? "Memproses" : "Unduh Sertifikat"}
|
||||||
@@ -160,7 +160,7 @@ export default function CertificateAvailable({ project, certificate, templateUrl
|
|||||||
{/* Bagikan ke LinkedIn */}
|
{/* Bagikan ke LinkedIn */}
|
||||||
<button
|
<button
|
||||||
onClick={handleShareLinkedIn}
|
onClick={handleShareLinkedIn}
|
||||||
className="flex items-center justify-center gap-2 w-full bg-[#0A66C2] hover:bg-[#004182] active:scale-95 transition-all text-white font-semibold py-2 rounded-xl text-sm"
|
className="flex items-center justify-center gap-2 w-full bg-[#0A66C2] hover:bg-[#004182] active:scale-95 transition-all text-white font-semibold py-2 rounded-xl text-sm hover:cursor-pointer"
|
||||||
>
|
>
|
||||||
{/* LinkedIn icon */}
|
{/* LinkedIn icon */}
|
||||||
<svg className="w-4 h-4 fill-white" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
<svg className="w-4 h-4 fill-white" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||||
@@ -174,12 +174,13 @@ export default function CertificateAvailable({ project, certificate, templateUrl
|
|||||||
<button
|
<button
|
||||||
onClick={handleDownloadImage}
|
onClick={handleDownloadImage}
|
||||||
disabled={downloadingImg}
|
disabled={downloadingImg}
|
||||||
className="flex flex-col items-center justify-center gap-1.5 border border-card-outline hover:bg-gray-50 active:scale-95 transition-all text-red-700 font-medium py-1 md:py-3.5 rounded-xl text-sm">
|
className="flex flex-col items-center justify-center gap-1.5 border border-card-outline hover:bg-gray-50 active:scale-95 transition-all text-red-700 font-medium py-1 md:py-3.5 rounded-xl text-sm hover:cursor-pointer"
|
||||||
|
>
|
||||||
<Printer className="w-4 h-4 md:w-5 md:h-5" />
|
<Printer className="w-4 h-4 md:w-5 md:h-5" />
|
||||||
<span className="text-xs md:text-sm">{downloadingImg ? "Memproses" : "Cetak"}</span>
|
<span className="text-xs md:text-sm">{downloadingImg ? "Memproses" : "Cetak"}</span>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
className="flex flex-col items-center justify-center gap-1.5 border border-card-outline hover:bg-gray-50 active:scale-95 transition-all text-red-700 font-medium py-1 md:py-3.5 rounded-xl text-sm"
|
className="flex flex-col items-center justify-center gap-1.5 border border-card-outline hover:bg-gray-50 active:scale-95 transition-all text-red-700 font-medium py-1 md:py-3.5 rounded-xl text-sm hover:cursor-pointer"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
navigator.clipboard.writeText(`${window.location.origin}/verify-certificate/${certificate.uuid}`);
|
navigator.clipboard.writeText(`${window.location.origin}/verify-certificate/${certificate.uuid}`);
|
||||||
customToast.success("Link berhasil disalin!", "Link sudah disalin ke clipboard");
|
customToast.success("Link berhasil disalin!", "Link sudah disalin ke clipboard");
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ const HomeProjectList = () => {
|
|||||||
if (error) return <p className="text-red-500 text-sm">{error}</p>;
|
if (error) return <p className="text-red-500 text-sm">{error}</p>;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className=''>
|
<div>
|
||||||
<h2 className="text-lg font-semibold text-font-shade mb-5">Projects</h2>
|
<h2 className="text-lg font-semibold text-font-shade mb-5">Projects</h2>
|
||||||
|
|
||||||
{projects.length === 0 ? (
|
{projects.length === 0 ? (
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ const HomeMentorPage = () => {
|
|||||||
<HomeHeader />
|
<HomeHeader />
|
||||||
<div className="flex flex-col gap-5">
|
<div className="flex flex-col gap-5">
|
||||||
<div className="">
|
<div className="">
|
||||||
<div className="bg-white border border-box-border rounded-xl p-6">
|
<div>
|
||||||
<HomeMentorProject />
|
<HomeMentorProject />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ const HomeMentorProject = () => {
|
|||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='flex flex-col'>
|
<div className='flex flex-col box'>
|
||||||
<div className='flex flex-row justify-between mb-3 items-center'>
|
<div className='flex flex-row justify-between mb-5 items-center'>
|
||||||
<h2 className="text-lg font-semibold text-gray-800">Projects</h2>
|
<h2 className="text-lg font-semibold text-gray-800">Projects</h2>
|
||||||
<button
|
<button
|
||||||
className='bg-card p-1.5 rounded-lg font-bold hover:bg-card-hover border border-card-outline'
|
className='bg-card p-1.5 rounded-lg font-bold hover:bg-card-hover border border-card-outline'
|
||||||
|
|||||||
@@ -23,13 +23,13 @@ async function ensureFontsLoaded(): Promise<void> {
|
|||||||
|
|
||||||
// LAYOUT DEFAULT SERTIFIKAT YANG AKAN DIGENERATE
|
// LAYOUT DEFAULT SERTIFIKAT YANG AKAN DIGENERATE
|
||||||
const LAYOUT = {
|
const LAYOUT = {
|
||||||
internName: { x: 0.54, y: 0.47, size: 130, font: "Great Vibes", color: "#800000" },
|
internName: { x: 0.56, y: 0.47, size: 130, font: "Great Vibes", color: "#800000" },
|
||||||
internNameSmall: { x: 0.82, y: 0.889, size: 47, font: "Great Vibes", color: "#090909" },
|
internNameSmall: { x: 0.82, y: 0.88, size: 42, font: "Great Vibes", color: "#090909" },
|
||||||
userposition: { x: 0.855, y: 0.557, size: 46, font: "Grenze", color: "#800000" },
|
userposition: { x: 0.85, y: 0.557, size: 46, font: "Grenze", color: "#800000" },
|
||||||
duration: { x: 0.7, y: 0.615, size: 48, font: "Grenze", color: "#090909" },
|
duration: { x: 0.7, y: 0.615, size: 48, font: "Grenze", color: "#090909" },
|
||||||
certNo: { x: 0.56, y: 0.305, size: 50, font: "Grenze", color: "#090909" },
|
certNo: { x: 0.56, y: 0.305, size: 50, font: "Grenze", color: "#090909" },
|
||||||
certNoSmall: { x: 0.827, y: 0.92, size: 32, font: "Grenze", color: "#090909"},
|
certNoSmall: { x: 0.827, y: 0.905, size: 30, font: "Grenze", color: "#090909"},
|
||||||
qr: { x: 0.772, y: 0.715, size: 0.103 },
|
qr: { x: 0.771, y: 0.715, size: 0.103 },
|
||||||
};
|
};
|
||||||
|
|
||||||
// HELPER: kurangi ukuran font 25% jika nama melebihi 22 karakter (termasuk spasi)
|
// HELPER: kurangi ukuran font 25% jika nama melebihi 22 karakter (termasuk spasi)
|
||||||
@@ -75,7 +75,7 @@ export async function generateCertificate(
|
|||||||
};
|
};
|
||||||
|
|
||||||
text(LAYOUT.internName, internName);
|
text(LAYOUT.internName, internName);
|
||||||
text(LAYOUT.internNameSmall, internName);
|
text(LAYOUT.internNameSmall, internName.trim().toLowerCase());
|
||||||
text(LAYOUT.userposition, userposition);
|
text(LAYOUT.userposition, userposition);
|
||||||
text(LAYOUT.duration, ProjectDuration);
|
text(LAYOUT.duration, ProjectDuration);
|
||||||
text(LAYOUT.certNo, certificateNo);
|
text(LAYOUT.certNo, certificateNo);
|
||||||
|
|||||||
+4
-1
@@ -57,7 +57,7 @@
|
|||||||
background-color: var(--color-box-primary);
|
background-color: var(--color-box-primary);
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
border: 1px solid var(--color-border);
|
border: 1px solid var(--color-border);
|
||||||
padding: 32px;
|
padding:12px;
|
||||||
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1),
|
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1),
|
||||||
0 2px 4px -2px rgba(0, 0, 0, 0.1);
|
0 2px 4px -2px rgba(0, 0, 0, 0.1);
|
||||||
}
|
}
|
||||||
@@ -135,6 +135,9 @@ dialog.custom-dialog::backdrop {
|
|||||||
padding-bottom: 1.25rem;
|
padding-bottom: 1.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.box {
|
||||||
|
padding: 32px;
|
||||||
|
}
|
||||||
.main-content {
|
.main-content {
|
||||||
padding-block: calc(var(--spacing) * 10);
|
padding-block: calc(var(--spacing) * 10);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user