Skip to content

Commit

Permalink
Merge pull request #22 from Programmer-RD-AI/6-create-and-configure-a…
Browse files Browse the repository at this point in the history
…rticle-card-component

Add and test Article Card component with styles and visual consistency
  • Loading branch information
Programmer-RD-AI authored Aug 8, 2024
2 parents 2cb3fb3 + ee928d1 commit 93b1027
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 0 deletions.
48 changes: 48 additions & 0 deletions cypress/e2e/user/articleCard.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// cypress/e2e/user/articleCard.cy.js

describe("ArticleCard", () => {
beforeEach(() => {
// Visit the page where the ArticleCard is displayed
cy.visit("/"); // Adjust this path if ArticleCard is on a different route
});

it("should display article card", () => {
// Ensure at least one card exists and is visible
cy.get(".article-card").first().should("exist").and("be.visible");
});

it("should display article title", () => {
// Ensure at least one card exists and is visible
cy.get(".article-card").first().should("exist").and("be.visible");

// Check if the title is present within the first card
cy.get(".article-card")
.first()
.within(() => {
cy.get("h6").should("exist").and("not.be.empty");
});
});

it("should display article summary", () => {
// Ensure at least one card exists and is visible
cy.get(".article-card").first().should("exist").and("be.visible");

// Check if the summary is present within the first card
cy.get(".article-card")
.first()
.within(() => {
cy.get("p").should("exist").and("not.be.empty");
});
});

it("should navigate to the article detail page on click", () => {
// Ensure at least one card exists and is visible
cy.get(".article-card").first().should("exist").and("be.visible");

// Click the first card to navigate
cy.get(".article-card").first().click();

// Verify that the URL includes the article ID
cy.url().should("include", "/article/");
});
});
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions src/assets/styles/ArticleCard.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/* ArticleCard.css */
.article-card {
height: 100%;
display: flex;
flex-direction: column;
}

.article-card:hover .card-content {
opacity: 1;
}

.card-content {
opacity: 0;
transition: opacity 0.3s ease;
overflow: hidden;
}
9 changes: 9 additions & 0 deletions src/components/ArticleCard.cy.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React from 'react'
import ArticleCard from './ArticleCard'

describe('<ArticleCard />', () => {
it('renders', () => {
// see: https://on.cypress.io/mounting-react
cy.mount(<ArticleCard />)
})
})
74 changes: 74 additions & 0 deletions src/components/ArticleCard.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import React from "react";
import { Card, CardContent, Typography, styled } from "@mui/material";
import { motion } from "framer-motion";
import { Link } from "react-router-dom";
import "../assets/styles/ArticleCard.css";

const StyledCard = styled(Card)({
borderRadius: "0",
overflow: "hidden",
display: "flex",
flexDirection: "column",
height: "100%",
position: "relative",
boxShadow: "0 4px 8px rgba(0,0,0,0.1)",
transition: "transform 0.3s ease, box-shadow 0.3s ease",
maxHeight: "300px",
});

const CardContentStyled = styled(CardContent)({
flex: 1,
display: "flex",
flexDirection: "column",
justifyContent: "center",
padding: "8px",
position: "absolute",
bottom: "0",
width: "100%",
backgroundColor: "rgba(0, 0, 0, 0.6)",
color: "white",
transition: "opacity 0.3s ease",
opacity: 0,
overflow: "hidden",
});

const StyledCardImage = styled("div")({
width: "100%",
height: "200px",
backgroundSize: "cover",
backgroundPosition: "center",
});

const ArticleCard = ({
title,
summary,
category,
author,
time,
image,
articleId,
}) => (
<Link
to={`/article/${articleId}`}
style={{ textDecoration: "none", color: "inherit" }}
>
<motion.div className="article-card">
<StyledCard>
<StyledCardImage style={{ backgroundImage: `url(${image})` }} />
<CardContentStyled className="card-content">
<Typography variant="subtitle2" color="text.secondary">
{category} | {author} | {time}
</Typography>
<Typography variant="h6" component="div" sx={{ mt: 1 }}>
{title}
</Typography>
<Typography variant="body2" sx={{ mt: 1 }}>
{summary}
</Typography>
</CardContentStyled>
</StyledCard>
</motion.div>
</Link>
);

export default ArticleCard;

0 comments on commit 93b1027

Please sign in to comment.