diff --git a/src/app/components/content/IsaacCard.tsx b/src/app/components/content/IsaacCard.tsx
index 0372ec600e..4a64a78dfd 100644
--- a/src/app/components/content/IsaacCard.tsx
+++ b/src/app/components/content/IsaacCard.tsx
@@ -5,19 +5,18 @@ import { apiHelper, isAppLink } from "../../services";
import { Link } from "react-router-dom";
import { IsaacCardDTO } from "../../../IsaacApiTypes";
-// NOTE: Currently not in use by CS. See ticket #212 for more details.
-
interface IsaacCardProps {
doc: IsaacCardDTO;
imageClassName?: string;
}
export const IsaacCard = ({ doc, imageClassName }: IsaacCardProps) => {
- const { title, subtitle, image, clickUrl, disabled, verticalContent } = doc;
+ const { title, subtitle, image, clickUrl, disabled, verticalContent, buttonText } = doc;
const classes = classNames({ "menu-card": true, disabled: disabled, "isaac-card-vertical": verticalContent });
const imgSrc = image?.src && apiHelper.determineImageUrl(image.src);
+ const showButton = Boolean(buttonText && clickUrl);
- const link =
+ const stretchedLink =
clickUrl && isAppLink(clickUrl) ? (
) : (
@@ -25,6 +24,28 @@ export const IsaacCard = ({ doc, imageClassName }: IsaacCardProps) => {
);
+ const button = (
+
+ {clickUrl && isAppLink(clickUrl) ? (
+
+ {buttonText}
+
+ ) : (
+
+ {buttonText}
+
+ )}
+
+ );
+
+ const footer = showButton ? button : clickUrl && stretchedLink;
+
return verticalContent ? (
{image && (
@@ -44,7 +65,7 @@ export const IsaacCard = ({ doc, imageClassName }: IsaacCardProps) => {
{subtitle}
- {clickUrl && link}
+ {footer}
) : (
@@ -65,7 +86,7 @@ export const IsaacCard = ({ doc, imageClassName }: IsaacCardProps) => {
- {clickUrl && link}
+ {footer}
);
};
diff --git a/src/scss/common/cards.scss b/src/scss/common/cards.scss
index ef9610d0de..b3c232ac45 100644
--- a/src/scss/common/cards.scss
+++ b/src/scss/common/cards.scss
@@ -272,3 +272,22 @@
.card-deck + .card-deck {
margin-top: 1.5rem;
}
+
+.isaac-card-link-container {
+ display: flex;
+ justify-content: center;
+ margin-top: 1.5rem;
+ padding: 0 0 1rem;
+}
+
+.isaac-card-link {
+ color: #6b009a;
+ font-size: 1.1875rem;
+ text-decoration: none;
+
+ &:hover,
+ &:focus {
+ color: #6b009a;
+ text-decoration: underline;
+ }
+}
diff --git a/src/test/components/content/IsaacCard.test.tsx b/src/test/components/content/IsaacCard.test.tsx
new file mode 100644
index 0000000000..cdf8570e40
--- /dev/null
+++ b/src/test/components/content/IsaacCard.test.tsx
@@ -0,0 +1,63 @@
+import { screen } from "@testing-library/react";
+import { renderTestEnvironment } from "../../utils";
+import { IsaacCard } from "../../../app/components/content/IsaacCard";
+import { IsaacCardDTO } from "../../../IsaacApiTypes";
+
+const renderIsaacCard = (doc: IsaacCardDTO) => {
+ renderTestEnvironment({
+ PageComponent: IsaacCard,
+ componentProps: { doc },
+ initialRouteEntries: ["/"],
+ role: "ANONYMOUS",
+ });
+};
+
+describe("IsaacCard", () => {
+ it("renders the title and subtitle", () => {
+ renderIsaacCard({ title: "Card title", subtitle: "Card subtitle", verticalContent: true });
+ expect(screen.getByText("Card title")).toBeInTheDocument();
+ expect(screen.getByText("Card subtitle")).toBeInTheDocument();
+ });
+
+ it("renders a custom, centred button when buttonText and clickUrl are provided", () => {
+ renderIsaacCard({
+ title: "Careers",
+ subtitle: "Explore computing careers",
+ clickUrl: "/careers_in_computer_science",
+ buttonText: "Read more",
+ verticalContent: true,
+ });
+ const button = screen.getByRole("link", { name: "Read more" });
+ expect(button).toBeInTheDocument();
+ expect(button).toHaveAttribute("href", "/careers_in_computer_science");
+ expect(button).toHaveClass("isaac-card-link");
+ expect(button.parentElement).toHaveClass("isaac-card-link-container");
+ });
+
+ it("opens external button links in a new tab", () => {
+ renderIsaacCard({
+ title: "External",
+ subtitle: "An external resource",
+ clickUrl: "https://example.com/resource",
+ buttonText: "Visit resource",
+ verticalContent: true,
+ });
+ const button = screen.getByRole("link", { name: "Visit resource" });
+ expect(button).toHaveAttribute("href", "https://example.com/resource");
+ expect(button).toHaveAttribute("target", "_blank");
+ expect(button).toHaveAttribute("rel", "noopener noreferrer");
+ });
+
+ it("falls back to a stretched whole-card link when no buttonText is provided", () => {
+ renderIsaacCard({
+ title: "Create a Group",
+ subtitle: "Create and manage student groups.",
+ clickUrl: "/groups",
+ verticalContent: true,
+ });
+ expect(screen.queryByRole("link", { name: /read more/i })).not.toBeInTheDocument();
+ const link = document.querySelector("a.stretched-link");
+ expect(link).toBeInTheDocument();
+ expect(link).toHaveAttribute("href", "/groups");
+ });
+});