Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
ec08a49
feat: implement horizontal footer layout with modern social media icons
Recxsmacx Jul 8, 2025
1c128a4
fix: add CSS support for tooltip visibility in Cypress tests
Recxsmacx Jul 8, 2025
edcde1c
feat: make footer responsive for mobile devices
Recxsmacx Jul 10, 2025
4909858
feat: make footer responsive for mobile devices
Recxsmacx Jul 10, 2025
c173a1d
Update footer.tsx with social components
Recxsmacx Jul 12, 2025
658699f
Merge latest master changes
Recxsmacx Aug 15, 2025
160b7c1
fix: Add JSX import to socials component and install react-dom types
Recxsmacx Aug 15, 2025
3ab5ad6
feat: Add AsyncAPI Conference 2025 PDF document
Recxsmacx Aug 15, 2025
ad84e00
Merge branch 'master' into Footer-socials
Recxsmacx Oct 11, 2025
2146a02
chore: sync package-lock.json with package.json
Recxsmacx Oct 11, 2025
c7da613
Merge branch 'master' into Footer-socials
Recxsmacx Oct 16, 2025
af65219
Merge branch 'master' into Footer-socials
AceTheCreator Oct 18, 2025
a37c9d6
Merge branch 'master' into Footer-socials
AceTheCreator Oct 18, 2025
24e1adf
Merge branch 'master' into Footer-socials
Recxsmacx Oct 28, 2025
f53e961
applied for each in cypress tests
Recxsmacx Oct 28, 2025
435354e
Merge branch 'Footer-socials' of https://github.com/Recxsmacx/confere…
Recxsmacx Oct 28, 2025
0338728
Delete cypress/Downloads/conf 2025.pdf
Recxsmacx Oct 28, 2025
e6edf25
imported pre available socials svgs
Recxsmacx Oct 28, 2025
b599645
Merge branch 'Footer-socials' of https://github.com/Recxsmacx/confere…
Recxsmacx Oct 28, 2025
338fff7
dependency issue resolved
Recxsmacx Oct 28, 2025
2b15c15
Merge branch 'master' into Footer-socials
Recxsmacx Oct 30, 2025
13d9c99
Merge branch 'master' into Footer-socials
Recxsmacx Nov 12, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 17 additions & 38 deletions components/Footer/footer.tsx
Original file line number Diff line number Diff line change
@@ -1,57 +1,36 @@
import React from 'react';
import Image from 'next/image';
import ILink from '../illustration/link';
import { Social } from '../../types/types';
import socials from '../../config/socials.json';
import React from "react";
import ILink from "../illustration/link";
import Socials from "./socials";

function Footer(): JSX.Element {
return (
<div className="container" data-test="footer">
<div
className="w-full flex justify-between items-center p-4 sm:flex-col sm:gap-3"
className="w-full flex flex-row justify-between items-center p-4 gap-4 flex-wrap"
data-test="footer-asyncAPI-logo"
>
<div className="mt-2 text-[14px] text-gray-100 sm:hidden">
{/* Code of Conduct Section */}
<div className="text-[16px] text-gray-100 flex items-center flex-shrink-0">
<a
href="https://github.com/asyncapi/community/blob/master/CODE_OF_CONDUCT.md"
target="_blank"
rel="noreferrer"
className="hover:underline text-white duration-200 ease-in-out flex items-center"
data-test="code-of-conduct"
>
<span> Code of Conduct </span>
<span>
<ILink className="w-4 ml-2" fill="white" />
</span>
<span>Code of Conduct</span>
<ILink className="w-4 ml-2" fill="white" />
</a>
</div>
<div></div>
<div className="flex items-center justify-between sm:flex-col sm:items-center">
<div className="text-white">
Made with ❤️ by AsyncAPI contributors. By the community for the
community!
</div>
<div className="w-[0.9px] h-4 bg-white ml-4 sm:hidden" />
<div className="ml-4 flex justify-between items-center gap-2 sm:mt-4">
{socials.map((social: Social, index) => {
return (
<a
key={index}
href={social.href}
target="_blank"
rel="noreferrer"
className="rounded-lg flex items-center justify-center hover:border-[#AD20E2] duration-150 ease-in-out"
data-test={`footer-${social.name}`}
>
<Image
src={social.imgUrl}
alt={social.name}
height={23}
width={23}
/>
</a>
);
})}

{/* "Made with ❤️" and Socials Section - Grouped together */}
<div className="flex flex-row items-center gap-4 text-center">
<span className="text-white text-[16px]">
Made with ❤️ by AsyncAPI contributors. By the community for the community!
</span>
<div className="w-[1px] h-6 bg-white" />
<div className="flex items-center gap-2 flex-shrink-0">
<Socials />
</div>
</div>
</div>
Expand Down
68 changes: 68 additions & 0 deletions components/Footer/socials.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import React from 'react';

function Socials(): JSX.Element {
return (
<div className="social-wrapper" data-test="social-wrapper">
<ul className="inline-flex list-none justify-center font-['Poppins',sans-serif]">
<li className="icon linkedin relative bg-white rounded-full m-[5px] w-[35px] h-[35px] text-lg flex justify-center items-center flex-col shadow-md cursor-pointer transition-all duration-200 hover:bg-[#0077b5] hover:text-white">
<a
href="https://www.linkedin.com/company/asyncapi"
target="_blank"
rel="noreferrer"
className="w-full h-full flex justify-center items-center"
data-test="footer-Linkedin"
>
<span className="tooltip absolute top-0 text-sm bg-white text-white py-[5px] px-[8px] rounded-md shadow-md opacity-0 pointer-events-none transition-all duration-300">LinkedIn</span>
<svg viewBox="0 0 448 512" height="1em" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path d="M100.28 448H7.4V148.9h92.88zm-46.44-341.5a53.27 53.27 0 1 1 53.26-53.27 53.27 53.27 0 0 1-53.26 53.27zM447.8 448h-92.63V302.4c0-34.7-.7-79.3-48.3-79.3s-55.7 37.8-55.7 76.9V448h-92.63V148.9h88.9v40.8h1.3c12.4-23.5 42.7-48.3 87.9-48.3 94 0 111.3 61.9 111.3 142.3V448z" />
</svg>
</a>
</li>
<li className="icon github relative bg-white rounded-full m-[5px] w-[35px] h-[35px] text-lg flex justify-center items-center flex-col shadow-md cursor-pointer transition-all duration-200 hover:bg-[#333] hover:text-white">
<a
href="https://github.com/asyncapi"
target="_blank"
rel="noreferrer"
className="w-full h-full flex justify-center items-center"
data-test="footer-Github"
>
<span className="tooltip absolute top-0 text-sm bg-white text-white py-[5px] px-[8px] rounded-md shadow-md opacity-0 pointer-events-none transition-all duration-300">GitHub</span>
<svg xmlns="http://www.w3.org/2000/svg" height="1.4em" fill="currentColor" viewBox="0 0 16 16">
<path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.58.82-2.14-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82a7.6 7.6 0 0 1 2-.27c.68 0 1.36.09 2 .27 1.53-1.03 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.14 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.012 8.012 0 0 0 16 8c0-4.42-3.58-8-8-8z" />
</svg>
</a>
</li>
<li className="icon twitter relative bg-white rounded-full m-[5px] w-[35px] h-[35px] text-lg flex justify-center items-center flex-col shadow-md cursor-pointer transition-all duration-200 hover:bg-[#333] hover:text-white">
<a
href="https://twitter.com/asyncapispec"
target="_blank"
rel="noreferrer"
className="w-full h-full flex justify-center items-center"
data-test="footer-Twitter(X)"
>
<span className="tooltip absolute top-0 text-sm bg-white text-white py-[5px] px-[8px] rounded-md shadow-md opacity-0 pointer-events-none transition-all duration-300">Twitter</span>
<svg xmlns="http://www.w3.org/2000/svg" height="1.4em" fill="currentColor" viewBox="0 0 24 24">
<path d="M3 3h18v18H3V3zm10.4 8.2l4.3-6.2h-1.4l-3.6 5.2-3-5.2H5.7l4.2 7.1-4.6 6.7h1.4l3.9-5.6 3.2 5.6h3.2l-4.6-7.6z"/>
</svg>
</a>
</li>
<li className="icon youtube relative bg-white rounded-full m-[5px] w-[35px] h-[35px] text-lg flex justify-center items-center flex-col shadow-md cursor-pointer transition-all duration-200 hover:bg-[#ff0000] hover:text-white">
<a
href="https://www.youtube.com/asyncapi"
target="_blank"
rel="noreferrer"
className="w-full h-full flex justify-center items-center"
data-test="footer-youtube"
>
<span className="tooltip absolute top-0 text-sm bg-white text-white py-[5px] px-[8px] rounded-md shadow-md opacity-0 pointer-events-none transition-all duration-300">YouTube</span>
<svg xmlns="http://www.w3.org/2000/svg" height="1.4em" fill="currentColor" viewBox="0 0 24 24">
<path d="M23.498 6.186a2.999 2.999 0 0 0-2.118-2.118C19.5 3.5 12 3.5 12 3.5s-7.5 0-9.38.568a2.999 2.999 0 0 0-2.118 2.118C0 8.07 0 12 0 12s0 3.93.502 5.814a2.999 2.999 0 0 0 2.118 2.118C4.5 20.5 12 20.5 12 20.5s7.5 0 9.38-.568a2.999 2.999 0 0 0 2.118-2.118C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.75 15.02V8.98L15.5 12l-5.75 3.02z" />
</svg>
</a>
</li>
</ul>
</div>
);
}

export default Socials;
87 changes: 61 additions & 26 deletions cypress/e2e/Footer.cy.ts
Original file line number Diff line number Diff line change
@@ -1,55 +1,90 @@
describe('Footer links', () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes are not related to your PR. This is probably caused by some formatter in your IDE. ensure only changes related to your PR are pushed

describe("Footer links", () => {
beforeEach(() => {
cy.visit('/');
cy.visit("/");
});

it('Footer Should be visible', () => {
cy.getTestData('footer').should('be.visible');
it("Footer Should be visible", () => {
cy.getTestData("footer").should("be.visible");
});

it('Footer Should contain Code of Conduct', () => {
cy.getTestData('footer').contains('Code of Conduct');
it("Footer Should contain Code of Conduct", () => {
cy.getTestData("footer").contains("Code of Conduct");
});

it('Code of Conduct should redirect to the correct page', () => {
cy.getTestData('code-of-conduct').invoke('removeAttr', 'target').click();
it("Code of Conduct should redirect to the correct page", () => {
cy.getTestData("code-of-conduct").invoke("removeAttr", "target").click();

cy.origin(
'https://github.com/asyncapi/community/blob/master/CODE_OF_CONDUCT.md',
"https://github.com/asyncapi/community/blob/master/CODE_OF_CONDUCT.md",
() => {
cy.url().should(
'eq',
'https://github.com/asyncapi/community/blob/master/CODE_OF_CONDUCT.md'
"eq",
"https://github.com/asyncapi/community/blob/master/CODE_OF_CONDUCT.md",
);
}
},
);
});

it('Github should redirect to correct page', () => {
cy.getTestData('footer-Github').invoke('removeAttr', 'target').click();
it("Github should redirect to correct page", () => {
cy.getTestData("footer-Github").invoke("removeAttr", "target").click();

cy.origin('https://github.com/asyncapi', () => {
cy.url().should('eq', 'https://github.com/asyncapi');
cy.origin("https://github.com/asyncapi", () => {
cy.url().should("eq", "https://github.com/asyncapi");
});
});

it('Linkedin should redirect to correct page', () => {
cy.getTestData('footer-Linkedin').invoke('removeAttr', 'target').click();
it("Linkedin should redirect to correct page", () => {
cy.getTestData("footer-Linkedin").invoke("removeAttr", "target").click();

cy.origin('https://www.linkedin.com/company/asyncapi/', () => {
cy.url().should('eq', 'https://www.linkedin.com/company/asyncapi/');
cy.origin("https://www.linkedin.com", () => {
cy.url().should("include", "linkedin.com/company/asyncapi");
});
});

it('Twitter(X) should redirect to correct page', () => {
cy.getTestData('footer-Twitter(X)').invoke('removeAttr', 'target').click();
it("Twitter(X) should redirect to correct page", () => {
cy.getTestData("footer-Twitter(X)").invoke("removeAttr", "target").click();

cy.origin('https://x.com/asyncapispec', () => {
cy.url().should('match', /.*asyncapispec.*/);
cy.origin("https://x.com", () => {
cy.url().should("include", "asyncapispec");
});
});

it('Should Contain AsycAPI Conference Logo', () => {
cy.getTestData('footer-asyncAPI-logo').should('be.visible');
it("Should Contain AsyncAPI Conference Logo", () => {
cy.getTestData("footer-asyncAPI-logo").should("be.visible");
});

describe("Social Media Icons", () => {
beforeEach(() => {
cy.visit("/");
});

it("Should display social media icons", () => {
cy.get(".social-wrapper").should("exist");
cy.get(".social-wrapper .icon").should("have.length.at.least", 4);
});

it("Should display tooltip when hovering over LinkedIn icon", () => {
cy.get(".social-wrapper .linkedin .tooltip").invoke('addClass', 'show-for-test');
cy.get(".social-wrapper .linkedin .tooltip").should("be.visible");
cy.get(".social-wrapper .linkedin .tooltip").should("contain", "LinkedIn");
});

it("Should display tooltip when hovering over GitHub icon", () => {
cy.get(".social-wrapper .github .tooltip").invoke('addClass', 'show-for-test');
cy.get(".social-wrapper .github .tooltip").should("be.visible");
cy.get(".social-wrapper .github .tooltip").should("contain", "GitHub");
});

it("Should display tooltip when hovering over Twitter icon", () => {
cy.get(".social-wrapper .twitter .tooltip").invoke('addClass', 'show-for-test');
cy.get(".social-wrapper .twitter .tooltip").should("be.visible");
cy.get(".social-wrapper .twitter .tooltip").should("contain", "Twitter");
});

it("Should display tooltip when hovering over YouTube icon", () => {
cy.get(".social-wrapper .youtube .tooltip").invoke('addClass', 'show-for-test');
cy.get(".social-wrapper .youtube .tooltip").should("be.visible");
cy.get(".social-wrapper .youtube .tooltip").should("contain", "YouTube");
});
});
});
Loading