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 logoHumic from "../assets/logo.png";
|
||||
|
||||
const internshipLinks = [
|
||||
{ label: "Beranda", path: "/" },
|
||||
{ label: "Tentang", path: "/about-us" },
|
||||
{ label: "Life At Humic", path: "" },
|
||||
{ label: "Life At Humic", path: "/internships" },
|
||||
{ label: "Our Developer", path: "/our-developer" }
|
||||
];
|
||||
|
||||
const externalLinks = [
|
||||
{ label: "Humic Website", href: "https://humic.telkomuniversity.ac.id/" },
|
||||
{ label: "Our Activity", href: "https://humic.telkomuniversity.ac.id/humicinmedia/" },
|
||||
{ label: "Life At Humic", href: "" },
|
||||
// { label: "Our Developer", href: "#" },
|
||||
{ label: "Life At Humic", href: "https://humic.telkomuniversity.ac.id/" },
|
||||
];
|
||||
|
||||
const socials = [
|
||||
{ label: "Instagram", icon: FaInstagram, href: "https://www.instagram.com/humicengineering/" },
|
||||
{ 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() {
|
||||
@@ -45,7 +43,7 @@ export function FooterIntern() {
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
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" />
|
||||
</a>
|
||||
@@ -60,12 +58,14 @@ export function FooterIntern() {
|
||||
<ul className="flex flex-col gap-0.5 font-semibold">
|
||||
{internshipLinks.map(({ label, path }) => (
|
||||
<li key={label}>
|
||||
<Link
|
||||
to={path}
|
||||
<a
|
||||
href={path}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-[12.5px] text-gray-600 hover:text-red-800 transition-colors"
|
||||
>
|
||||
{label}
|
||||
</Link>
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
@@ -59,19 +59,19 @@ const Navbar = () => {
|
||||
<div className="hidden md:flex items-center gap-8 text-[18px] font-semibold">
|
||||
<button
|
||||
onClick={() => navigate("/about-us")}
|
||||
className="hover:text-gray-600 transition cursor-pointer"
|
||||
className="hover:text-blue-600 transition cursor-pointer"
|
||||
>
|
||||
About Us
|
||||
</button>
|
||||
<button
|
||||
onClick={handleContactClick}
|
||||
className="hover:text-gray-600 transition cursor-pointer"
|
||||
className="hover:text-blue-600 transition cursor-pointer"
|
||||
>
|
||||
Contact Us
|
||||
</button>
|
||||
<button
|
||||
onClick={() => navigate("/internships")}
|
||||
className="hover:text-gray-600 transition cursor-pointer"
|
||||
className="hover:text-grblueay-600 transition cursor-pointer"
|
||||
>
|
||||
Internship
|
||||
</button>
|
||||
@@ -80,7 +80,7 @@ const Navbar = () => {
|
||||
onClick={() => {
|
||||
navigate("/login-internify");
|
||||
}}
|
||||
className="hover:text-red-600 transition cursor-pointer"
|
||||
className="hover:text-blue-600 transition cursor-pointer"
|
||||
>
|
||||
Portal LMS
|
||||
</button>
|
||||
|
||||
@@ -103,11 +103,13 @@ export default function HomeCalendar() {
|
||||
|
||||
return (
|
||||
<div className="box">
|
||||
<div className="flex flex-col py-4">
|
||||
{/* 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">
|
||||
{MONTH_NAMES[currentMonth]} {currentYear}
|
||||
</h2>
|
||||
|
||||
<div className="flex items-center">
|
||||
<button
|
||||
onClick={prevMonth}
|
||||
@@ -116,6 +118,7 @@ export default function HomeCalendar() {
|
||||
>
|
||||
<ChevronLeft className="w-4 h-4 text-gray-500" />
|
||||
</button>
|
||||
|
||||
<button
|
||||
onClick={nextMonth}
|
||||
className="p-1 rounded hover:bg-gray-100 transition-colors"
|
||||
@@ -126,34 +129,46 @@ export default function HomeCalendar() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-7 mb-1 px-5">
|
||||
{DAY_LABELS.map(day => (
|
||||
<div key={day} className="text-center text-xs text-gray-400 font-medium py-1">
|
||||
<div className="grid grid-cols-7 mb-1 px-10 md:px-0">
|
||||
{DAY_LABELS.map((day) => (
|
||||
<div
|
||||
key={day}
|
||||
className="text-center text-xs text-gray-400 font-medium py-1"
|
||||
>
|
||||
{day}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-7 px-5">
|
||||
{/* Trailing days from prev month */}
|
||||
{trailingDays.map(day => (
|
||||
<div className="grid grid-cols-7 px-10 md:px-0">
|
||||
{/* Trailing days from previous month */}
|
||||
{trailingDays.map((day) => (
|
||||
<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>
|
||||
))}
|
||||
|
||||
{currentDays.map(day => (
|
||||
<div key={day} className="flex justify-center items-center py-1">
|
||||
{currentDays.map((day) => (
|
||||
<div
|
||||
key={day}
|
||||
className="flex justify-center items-center py-1"
|
||||
>
|
||||
<div className="w-7 flex items-center justify-center">
|
||||
{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}
|
||||
</span>
|
||||
) : (
|
||||
<span
|
||||
className={`w-full h-7 flex items-center justify-center text-xs
|
||||
${isBold(day) ? 'font-bold text-gray-800' : 'text-gray-700'}
|
||||
${hasDeadline(day) ? 'bg-red text-white rounded-full' : ''}
|
||||
${isBold(day)
|
||||
? "font-bold text-gray-800"
|
||||
: "text-gray-700"
|
||||
}
|
||||
${hasDeadline(day)
|
||||
? "bg-red text-white rounded-full"
|
||||
: ""
|
||||
}
|
||||
transition-colors`}
|
||||
>
|
||||
{day}
|
||||
@@ -164,34 +179,40 @@ export default function HomeCalendar() {
|
||||
))}
|
||||
|
||||
{/* Leading days from next month */}
|
||||
{leadingDays.map(day => (
|
||||
{leadingDays.map((day) => (
|
||||
<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>
|
||||
|
||||
{/* Divider */}
|
||||
<hr className="my-3 border-box-border" />
|
||||
<hr className="my-1.5 border-box-border" />
|
||||
|
||||
{/* 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">
|
||||
Upcoming Deadlines
|
||||
</p>
|
||||
|
||||
{upcomingDeadlines.length > 0 ? (
|
||||
<ul className="flex flex-col gap-1">
|
||||
{upcomingDeadlines.map((d, i) => (
|
||||
<li key={i} className="flex items-center gap-2">
|
||||
<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>
|
||||
))}
|
||||
</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>
|
||||
);
|
||||
}
|
||||
@@ -151,7 +151,7 @@ export default function CertificateAvailable({ project, certificate, templateUrl
|
||||
<button
|
||||
onClick={handleDownloadPdf}
|
||||
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" />
|
||||
{downloadingPdf ? "Memproses" : "Unduh Sertifikat"}
|
||||
@@ -160,7 +160,7 @@ export default function CertificateAvailable({ project, certificate, templateUrl
|
||||
{/* Bagikan ke LinkedIn */}
|
||||
<button
|
||||
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 */}
|
||||
<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
|
||||
onClick={handleDownloadImage}
|
||||
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" />
|
||||
<span className="text-xs md:text-sm">{downloadingImg ? "Memproses" : "Cetak"}</span>
|
||||
</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={() => {
|
||||
navigator.clipboard.writeText(`${window.location.origin}/verify-certificate/${certificate.uuid}`);
|
||||
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>;
|
||||
|
||||
return (
|
||||
<div className=''>
|
||||
<div>
|
||||
<h2 className="text-lg font-semibold text-font-shade mb-5">Projects</h2>
|
||||
|
||||
{projects.length === 0 ? (
|
||||
|
||||
@@ -8,7 +8,7 @@ const HomeMentorPage = () => {
|
||||
<HomeHeader />
|
||||
<div className="flex flex-col gap-5">
|
||||
<div className="">
|
||||
<div className="bg-white border border-box-border rounded-xl p-6">
|
||||
<div>
|
||||
<HomeMentorProject />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -28,8 +28,8 @@ const HomeMentorProject = () => {
|
||||
|
||||
|
||||
return (
|
||||
<div className='flex flex-col'>
|
||||
<div className='flex flex-row justify-between mb-3 items-center'>
|
||||
<div className='flex flex-col box'>
|
||||
<div className='flex flex-row justify-between mb-5 items-center'>
|
||||
<h2 className="text-lg font-semibold text-gray-800">Projects</h2>
|
||||
<button
|
||||
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
|
||||
const LAYOUT = {
|
||||
internName: { x: 0.54, y: 0.47, size: 130, font: "Great Vibes", color: "#800000" },
|
||||
internNameSmall: { x: 0.82, y: 0.889, size: 47, font: "Great Vibes", color: "#090909" },
|
||||
userposition: { x: 0.855, y: 0.557, size: 46, font: "Grenze", color: "#800000" },
|
||||
internName: { x: 0.56, y: 0.47, size: 130, font: "Great Vibes", color: "#800000" },
|
||||
internNameSmall: { x: 0.82, y: 0.88, size: 42, font: "Great Vibes", color: "#090909" },
|
||||
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" },
|
||||
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"},
|
||||
qr: { x: 0.772, y: 0.715, size: 0.103 },
|
||||
certNoSmall: { x: 0.827, y: 0.905, size: 30, font: "Grenze", color: "#090909"},
|
||||
qr: { x: 0.771, y: 0.715, size: 0.103 },
|
||||
};
|
||||
|
||||
// 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.internNameSmall, internName);
|
||||
text(LAYOUT.internNameSmall, internName.trim().toLowerCase());
|
||||
text(LAYOUT.userposition, userposition);
|
||||
text(LAYOUT.duration, ProjectDuration);
|
||||
text(LAYOUT.certNo, certificateNo);
|
||||
|
||||
+4
-1
@@ -57,7 +57,7 @@
|
||||
background-color: var(--color-box-primary);
|
||||
border-radius: 20px;
|
||||
border: 1px solid var(--color-border);
|
||||
padding: 32px;
|
||||
padding:12px;
|
||||
box-shadow: 0 4px 6px -1px 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;
|
||||
}
|
||||
|
||||
.box {
|
||||
padding: 32px;
|
||||
}
|
||||
.main-content {
|
||||
padding-block: calc(var(--spacing) * 10);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user