Skip to content

Commit e053fc7

Browse files
authored
Merge pull request #33 from hammer-code/feat/announcement
Show PDD2024 event announcement
2 parents 8b61003 + d088072 commit e053fc7

File tree

9 files changed

+111
-21
lines changed

9 files changed

+111
-21
lines changed

src/app/[locale]/layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export default async function LocaleRootLayout({ children, params: { locale } }:
4040
<head>
4141
<link rel="icon" href="/assets/icons/ic_hmc-dark.svg" sizes="any" />
4242
</head>
43-
<body className={sora.className}>
43+
<body className={`${sora.className} pt-8`}>
4444
<NextIntlClientProvider messages={messages}>
4545
<Wrapper>{children}</Wrapper>
4646
</NextIntlClientProvider>

src/components/common/footer/Footer.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@ const Footer = () => {
5353
<div className="flex flex-col md:items-start items-center gap-3">
5454
<h3 className="text-lg text-hmc-primary font-semibold">{t("contact.title")}</h3>
5555
<div className="flex flex-col md:items-start items-center gap-1">
56-
{contact.data.map((data) => (
56+
{contact.data.map((data, index) => (
5757
<Button
58-
key={data.navigate_url}
58+
key={index}
5959
variant="link"
6060
asChild
6161
className="!h-auto !p-0 md:text-sm justify-start text-xs font-normal text-slate-600 dark:text-slate-400 hover:opacity-80"

src/components/common/navbar/index.tsx

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,28 +6,32 @@ import { useTranslations } from "next-intl";
66
import LocaleToggle from "../locale-toggle";
77
import { LINK } from "./constant";
88
import Sidebar from "../sidebar";
9+
import AnnouncementLayout from "@/components/layout/announcement";
910

1011
const Navbar = () => {
1112
const t = useTranslations("Layout");
1213
return (
13-
<header className="border-b fixed w-full top-0 bg-white dark:bg-slate-950 z-50">
14-
<div className="container mx-auto py-5">
15-
<div className="flex items-center justify-between gap-4">
16-
<Link href="/">
17-
<div className="w-10 h-8 bg-[url('/assets/icons/ic_hmc-light.svg')] dark:bg-[url('/assets/icons/ic_hmc-dark.svg')] bg-cover bg-center"></div>
18-
</Link>
14+
<header className="fixed w-full z-50 top-0">
15+
<AnnouncementLayout />
16+
<div className="border-b bg-white dark:bg-slate-950">
17+
<div className="container mx-auto py-5">
18+
<div className="flex items-center justify-between gap-4">
19+
<Link href="/">
20+
<div className="w-10 h-8 bg-[url('/assets/icons/ic_hmc-light.svg')] dark:bg-[url('/assets/icons/ic_hmc-dark.svg')] bg-cover bg-center"></div>
21+
</Link>
1922

20-
<nav className="lg:flex items-center gap-7 hidden">
21-
{LINK.map(({ href, id }) => (
22-
<NavbarList key={id} href={href} title={t(`navbar.link-${id}`)} />
23-
))}
24-
<div className="flex gap-2 items-center">
25-
<ModeToggle />
26-
<LocaleToggle />
23+
<nav className="lg:flex items-center gap-7 hidden">
24+
{LINK.map(({ href, id }) => (
25+
<NavbarList key={id} href={href} title={t(`navbar.link-${id}`)} />
26+
))}
27+
<div className="flex gap-2 items-center">
28+
<ModeToggle />
29+
<LocaleToggle />
30+
</div>
31+
</nav>
32+
<div className="lg:hidden flex">
33+
<Sidebar />
2734
</div>
28-
</nav>
29-
<div className="lg:hidden flex">
30-
<Sidebar />
3135
</div>
3236
</div>
3337
</div>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { Announcement } from "@/components/ui/announcement";
2+
import { useTranslations } from "next-intl";
3+
4+
export default function AnnouncementLayout() {
5+
const t = useTranslations("Announcement");
6+
const pdd: { message: string; url: string } = {
7+
message: t("pdd-2024"),
8+
url: "https://pdd2024.hammercode.org/",
9+
};
10+
return (
11+
<div>
12+
<Announcement message={pdd.message} url={pdd.url} />
13+
</div>
14+
);
15+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { render } from "@testing-library/react";
2+
import { Announcement } from "./announcement";
3+
import userEvent from "@testing-library/user-event";
4+
5+
describe("Announcement", () => {
6+
it("renders correctly", async () => {
7+
const message = "An event is happening!";
8+
9+
const { getByRole, queryByRole } = render(<Announcement message={message} />);
10+
11+
expect(getByRole("alert")).toHaveTextContent("An event is happening!");
12+
13+
await userEvent.click(getByRole("button"));
14+
15+
expect(queryByRole("alert")).not.toBeInTheDocument();
16+
});
17+
18+
it("renders clickable link", async () => {
19+
const message = "An event is happening!";
20+
const link = "https://event.com/awesome-event";
21+
22+
const { getByRole } = render(<Announcement message={message} url={link} />);
23+
24+
expect(getByRole("link")).toHaveTextContent("An event is happening!");
25+
expect(getByRole("link")).toHaveAttribute("href", link);
26+
});
27+
});

src/components/ui/announcement.tsx

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { X } from "lucide-react";
2+
import { useState } from "react";
3+
4+
export interface AnnouncementProps {
5+
message: string;
6+
url?: string;
7+
}
8+
9+
function Announcement({ message, url }: AnnouncementProps) {
10+
const [hidden, setHidden] = useState(false);
11+
if (hidden) return null;
12+
const messageEl = url ? (
13+
<a href={url} target="_blank">
14+
{message}
15+
</a>
16+
) : (
17+
message
18+
);
19+
return (
20+
<div
21+
role="alert"
22+
className="bg-slate-950 flex justify-center items-center gap-2 text-white text-center px-4 py-2 text-sm md:text-normal"
23+
>
24+
{messageEl}
25+
<button onClick={() => setHidden(true)} className="bg-slate-500 rounded-full p-1 ">
26+
<X className="h-4 w-4" />
27+
<span className="sr-only">Close</span>
28+
</button>
29+
</div>
30+
);
31+
}
32+
33+
export { Announcement };

src/features/events/components/__test__/card.test.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { render, screen } from "@testing-library/react";
22
import CardEvent from "../Card";
33
import { EventType } from "../../types";
4+
import { NextIntlClientProvider } from "next-intl";
45

56
const mockData: EventType = {
67
id: "1",
@@ -17,12 +18,16 @@ const mockData: EventType = {
1718

1819
describe("CardEvent Component", () => {
1920
it("renders correctly with provided data", () => {
20-
render(<CardEvent data={mockData} />);
21+
render(
22+
<NextIntlClientProvider timeZone="Europe/London" locale="en" messages={{}}>
23+
<CardEvent data={mockData} />
24+
</NextIntlClientProvider>
25+
);
2126

2227
expect(screen.getByAltText("Advanced Frontend Workshop")).toBeInTheDocument();
2328
expect(screen.getByText("Advanced Frontend Workshop")).toBeInTheDocument();
2429
expect(screen.getByText("closed")).toBeInTheDocument();
25-
expect(screen.getByText("2024-09-15")).toBeInTheDocument();
30+
expect(screen.getByText("September 15, 2024")).toBeInTheDocument();
2631
expect(screen.getByText("3 hours")).toBeInTheDocument();
2732
expect(screen.getByText("San Francisco")).toBeInTheDocument();
2833
});

src/locales/en.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,5 +109,8 @@
109109
"event-3": "Instagram Live",
110110
"event-4": "Weekly Lesson"
111111
}
112+
},
113+
"Announcement": {
114+
"pdd-2024": "🚀 Hi there! Our annual tech conference Palu Developer Day is around the corner! Check it out!"
112115
}
113116
}

src/locales/id.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,5 +109,8 @@
109109
"event-3": "Siaran Langsung Instagram",
110110
"event-4": "Pembelajaran Mingguan"
111111
}
112+
},
113+
"Announcement": {
114+
"pdd-2024": "🚀 Halo! Acara tahunan teknologi Palu Developer Day sudah dekat! Klik di sini!"
112115
}
113116
}

0 commit comments

Comments
 (0)