Skip to content

Commit

Permalink
Merge pull request #320 from Trendyol/announcement-banner
Browse files Browse the repository at this point in the history
chore: announcement banner add
  • Loading branch information
armagandalkiran authored Feb 23, 2025
2 parents 861fc62 + 9edf9be commit 2f8d86e
Show file tree
Hide file tree
Showing 7 changed files with 248 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ const GroomingBoard = ({
editVoteClicked,
setEditVoteClicked,
jiraSidebarExpanded,
setJiraSidebarExpanded,
isAnnouncementBannerVisible
} = useGroomingRoom();

const { showLoader } = useLoader();
Expand Down Expand Up @@ -154,7 +154,7 @@ const GroomingBoard = ({
}

return (
<div className={classNames("grooming-board", {jiraSidebarExpanded: jiraSidebarExpanded})}>
<div className={classNames("grooming-board", {jiraSidebarExpanded: jiraSidebarExpanded, announcementBannerActive: isAnnouncementBannerVisible})}>
{showLoader && <Loading />}
<section
className={classNames("grooming-board__playground", {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { useGroomingRoom } from '@/contexts/GroomingRoomContext';
import { useState, useEffect } from 'react';

const announcements = [
{
id: 1,
icon: "✨",
text: "Hey there! We'd love to hear your thoughts on our new Jira design. Your feedback shapes our future!",
buttonText: "Share Thoughts",
link: process.env.NEXT_PUBLIC_FEEDBACK_SHEET_LINK,
},
{
id: 3,
icon: "💡",
text: "Got ideas for making GuruBu better? We're all ears!",
buttonText: "Give Feedback",
link: process.env.NEXT_PUBLIC_FEEDBACK_SHEET_LINK,
}
];

const AnnouncementBanner = () => {
const [currentIndex, setCurrentIndex] = useState(0);
const [isAnimating, setIsAnimating] = useState(false);
const { isAnnouncementBannerVisible, setIsAnnouncementBannerVisible } = useGroomingRoom();

useEffect(() => {
const interval = setInterval(() => {
setIsAnimating(true);
setTimeout(() => {
setCurrentIndex((prev) => (prev + 1) % announcements.length);
setIsAnimating(false);
}, 500); // Animation duration
}, 5000); // Change announcement every 10 seconds

return () => clearInterval(interval);
}, []);

if (!isAnnouncementBannerVisible) {
return null;
}

const currentAnnouncement = announcements[currentIndex];

const handleActionClick = () => {
window.open(currentAnnouncement.link, '_blank');
setIsAnnouncementBannerVisible(false);
};

return (
<div className="announcement-banner">
<div className="announcement-banner__content">
<div className={`announcement-banner__icon ${isAnimating ? 'animate-out' : ''}`}>
{currentAnnouncement.icon}
</div>
<p className={`announcement-banner__text ${isAnimating ? 'animate-out' : ''}`}>
{currentAnnouncement.text}
</p>
<button
className={`announcement-banner__button ${isAnimating ? 'animate-out' : ''}`}
onClick={handleActionClick}
>
{currentAnnouncement.buttonText}
</button>
<button
className="announcement-banner__close"
onClick={() => setIsAnnouncementBannerVisible(false)}
aria-label="Close announcement"
>
×
</button>
</div>
</div>
);
};

export default AnnouncementBanner;
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { Modal } from "@/components/common/modal";
import { ImportJiraIssuesForm } from "@/components/room/grooming-navbar/import-jira-issues";
import { GroomingMode } from "@/shared/enums";
import { AnnouncementTooltip } from "./announcement-tooltip";
import AnnouncementBanner from "./announcement-banner";
import classNames from "classnames";

interface Props {
Expand Down Expand Up @@ -63,47 +64,50 @@ const GroomingNavbar = ({ showNickNameForm, roomId }: Props) => {
};

return (
<nav className="grooming-navbar">
<div className={classNames("grooming-navbar__content", { "jira-sidebar-expanded": jiraSidebarExpanded })}>
<Logo />
<div className="grooming-navbar__content-right">
<div className="grooming-navbar__content-actions">
{userInfo.lobby?.isAdmin &&
groomingInfo?.mode === GroomingMode.PlanningPoker && (
<div>
<button
className="grooming-navbar__content-import-jira-issues"
onClick={() => openModal("importJiraIssues")}
>
<IconFileImport size={20} />
Import Jira Issues
</button>
</div>
)}
<button
className="grooming-navbar__content-copy-link"
onClick={handleCopyGroomingLinkClick}
>
{isGroomingLinkCopied ? (
<IconClipboardCheck size={20} />
) : (
<IconCopy size={20} />
)}
Link
</button>
</div>
<div className="grooming-navbar__content-user-section">
<Timer roomId={roomId} />
<ThemeSelector />
<AnnouncementTooltip />
<GroomingBoardProfile roomId={roomId} />
<>
<AnnouncementBanner />
<nav className={classNames("grooming-navbar", { "grooming-navbar--nickname-form": showNickNameForm })}>
<div className={classNames("grooming-navbar__content", { "jira-sidebar-expanded": jiraSidebarExpanded })}>
<Logo />
<div className="grooming-navbar__content-right">
<div className="grooming-navbar__content-actions">
{userInfo.lobby?.isAdmin &&
groomingInfo?.mode === GroomingMode.PlanningPoker && (
<div>
<button
className="grooming-navbar__content-import-jira-issues"
onClick={() => openModal("importJiraIssues")}
>
<IconFileImport size={20} />
Import Jira Issues
</button>
</div>
)}
<button
className="grooming-navbar__content-copy-link"
onClick={handleCopyGroomingLinkClick}
>
{isGroomingLinkCopied ? (
<IconClipboardCheck size={20} />
) : (
<IconCopy size={20} />
)}
Link
</button>
</div>
<div className="grooming-navbar__content-user-section">
<Timer roomId={roomId} />
<ThemeSelector />
<AnnouncementTooltip />
<GroomingBoardProfile roomId={roomId} />
</div>
</div>
<Modal isOpen={modalOpen} onClose={closeModal}>
<ImportJiraIssuesForm roomId={roomId} closeModal={closeModal} />
</Modal>
</div>
<Modal isOpen={modalOpen} onClose={closeModal}>
<ImportJiraIssuesForm roomId={roomId} closeModal={closeModal} />
</Modal>
</div>
</nav>
</nav>
</>
);
};

Expand Down
11 changes: 9 additions & 2 deletions gurubu-client/src/app/contexts/GroomingRoomContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ interface GroomingContextValues {
setCurrentJiraIssueIndex: (value: number) => void;
jiraSidebarExpanded: boolean;
setJiraSidebarExpanded: (value: boolean) => void;
isAnnouncementBannerVisible: boolean;
setIsAnnouncementBannerVisible: (value: boolean) => void;
}

const GroomingRoomContext = createContext({} as GroomingContextValues);
Expand All @@ -40,6 +42,7 @@ export function GroomingRoomProvider({ children, roomId }: GroomingRoomProviderP
const [editVoteClicked, setEditVoteClicked] = useState(false);
const [currentJiraIssueIndex, setCurrentJiraIssueIndex] = useState(0);
const [jiraSidebarExpanded, setJiraSidebarExpanded] = useState(false);
const [isAnnouncementBannerVisible, setIsAnnouncementBannerVisible] = useState(true);

useEffect(() => {
const nickname = localStorage.getItem("nickname");
Expand Down Expand Up @@ -74,7 +77,9 @@ export function GroomingRoomProvider({ children, roomId }: GroomingRoomProviderP
currentJiraIssueIndex,
setCurrentJiraIssueIndex,
jiraSidebarExpanded,
setJiraSidebarExpanded
setJiraSidebarExpanded,
isAnnouncementBannerVisible,
setIsAnnouncementBannerVisible
}),
[
roomStatus,
Expand All @@ -94,7 +99,9 @@ export function GroomingRoomProvider({ children, roomId }: GroomingRoomProviderP
currentJiraIssueIndex,
setCurrentJiraIssueIndex,
jiraSidebarExpanded,
setJiraSidebarExpanded
setJiraSidebarExpanded,
isAnnouncementBannerVisible,
setIsAnnouncementBannerVisible
]
);
return <GroomingRoomContext.Provider value={values}>{children}</GroomingRoomContext.Provider>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
padding-inline: 0;
margin-inline: 16px;
}
&.announcementBannerActive{
height: calc(100vh - 225px);
}
&__playground {
width: 60%;
display: flex;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
.announcement-banner {
background: linear-gradient(90deg, $primary-600 0%, $primary-700 100%);
padding: 10px 0;
width: 100%;
overflow: hidden;
position: relative;

&__content {
max-width: 1200px;
margin: 0 auto;
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
padding: 0 24px;
position: relative;
}

&__close {
background: none;
border: none;
color: rgba($white, 0.8);
font-size: 20px;
line-height: 1;
padding: 4px 6px;
cursor: pointer;
position: absolute;
right: 24px;
top: 50%;
transform: translateY(-50%);
transition: color 0.2s ease;
display: flex;
align-items: center;
justify-content: center;

&:hover {
color: $white;
}
}

&__icon {
font-size: 14px;
transition: transform 0.5s ease, opacity 0.5s ease;
transform-origin: center;

&.animate-out {
transform: translateY(-20px);
opacity: 0;
}

&:not(.animate-out) {
animation: slideIn 0.5s ease;
}
}

&__text {
color: $white;
font-size: $font-size-paragraph-4;
font-weight: $medium;
letter-spacing: 0.2px;
margin: 0;
transition: transform 0.5s ease, opacity 0.5s ease;
transform-origin: center;

&.animate-out {
transform: translateY(-20px);
opacity: 0;
}

&:not(.animate-out) {
animation: slideIn 0.5s ease;
}
}

&__button {
background-color: $white;
color: $primary-700;
border: none;
padding: 4px 10px;
border-radius: $radius-medium;
font-size: $font-size-paragraph-5;
font-weight: $semibold;
cursor: pointer;
white-space: nowrap;
transition: transform 0.5s ease, opacity 0.5s ease, background-color 0.2s ease;
transform-origin: center;

&.animate-out {
transform: translateY(-20px);
opacity: 0;
}

&:not(.animate-out) {
animation: slideIn 0.5s ease;
}

&:hover {
background-color: rgba($white, 0.9);
transform: translateY(-1px);
}
}
}

@keyframes slideIn {
from {
transform: translateY(20px);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
3 changes: 2 additions & 1 deletion gurubu-client/src/app/styles/room/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
@import "../mixins.scss";

@import "./grooming-navbar/grooming-navbar.scss";
@import "./grooming-navbar/announcement-tooltip.scss";
@import "./grooming-navbar/grooming-board-profile.scss";
@import "./grooming-navbar/announcement-banner.scss";
@import "./grooming-navbar/change-name.scss";
@import "./grooming-navbar/change-avatar.scss";
@import "./grooming-navbar/leave-room.scss";
@import "./grooming-navbar/timer.scss";
@import "./grooming-navbar/import-jira-issues.scss";
@import "./grooming-navbar/announcement-tooltip.scss";
@import "./grooming-board/vote-card.scss";
@import "./grooming-board/vote-card-v2.scss";
@import "./grooming-board/voting-stick.scss";
Expand Down

0 comments on commit 2f8d86e

Please sign in to comment.