Fakultas Ilmu Komputer UI

Commit 6014fcc1 authored by Muhammad Fairuzi Teguh's avatar Muhammad Fairuzi Teguh
Browse files

[REFACTOR] integrate artikel with Dhita's styling

parent efe5633b
Pipeline #48879 passed with stages
in 2 minutes and 6 seconds
......@@ -12,6 +12,6 @@ class ArtikelFactory(factory.DjangoModelFactory):
class Meta:
model = Artikel
title = fake.sentence()
title = fake.sentence()[:-1]
featured_image = os.path.join("edukasi", "placeholder.jpg")
content = "\n".join(fake.paragraphs())
......@@ -19,7 +19,7 @@ class Command(BaseCommand):
for i in range(5):
content.append(" ".join(fake.paragraphs()))
Artikel.objects.create(
title=fake.sentence(),
title=fake.sentence()[:-1],
featured_image=os.path.join("edukasi", random.choice([ # NOSONAR
"placeholder1.jpg", "placeholder2.jpg", "placeholder3.jpg"])),
content="\n".join(content)
......
......@@ -31,7 +31,6 @@ const Navbar = () => {
<Nav className="mr-auto">
<NavLink to="/">Home</NavLink>
<NavLink to="/jadwal-donor">Jadwal Donor</NavLink>
<NavLink to="/edukasi">Edukasi</NavLink>
<Button
variant="red-transparent"
onClick={
......
......@@ -32,7 +32,8 @@ describe(`Navbar`, () => {
const { container } = render(<Navbar />)
expect(container).toHaveTextContent("Home")
expect(container).toHaveTextContent("Jadwal Donor")
expect(container).toHaveTextContent("Edukasi")
expect(container).toHaveTextContent("Ajukan Acara Donor")
expect(container).toHaveTextContent("Kumpulan Artikel")
})
})
......
.article .column {
margin: 15px 15px 0;
padding: 0;
}
.article .column:last-child {
padding-bottom: 60px;
}
.article .column::after {
content: "";
clear: both;
display: block;
}
.article .column div {
position: relative;
float: left;
width: 300px;
margin: 0 0 0 25px;
padding: 0;
}
.article .column div:first-child {
margin-left: 0;
}
.article .column div span {
position: absolute;
bottom: -70px;
left: 0;
z-index: -1;
display: block;
width: 300px;
margin: 0;
padding: 0;
color: #444;
font-size: 18px;
text-decoration: none;
text-align: center;
-webkit-transition: 0.3s ease-in-out;
transition: 0.3s ease-in-out;
opacity: 0;
}
.article figure {
width: 300px;
margin: 0;
padding: 0;
background: #fff;
overflow: hidden;
}
.article figure:hover + span {
bottom: -55px;
opacity: 1;
}
import { Router } from "@reach/router"
import React from "react"
import { Col, Container, Row } from "react-bootstrap"
import { useQuery } from "react-query"
import { getArtikelEdukasi } from "../api"
import { getArtikelEdukasi, getListArtikelEdukasi } from "../api"
import ErrorRetry from "../components/error-retry"
import Layout from "../components/layout"
import SEO from "../components/seo"
import Spinner from "../components/spinner"
import { Link } from "gatsby"
import "./article.css"
const Content = props => {
const articleId = props.id
......@@ -21,6 +24,11 @@ const Content = props => {
.map(text => "<p>" + text + "</p>")
.join(" ")
: ""
const {
status: statusList,
data: dataList,
refetch: refetchList,
} = useQuery("artikel-edukasi", () => getListArtikelEdukasi(1))
return (
<Layout navbar>
<SEO title={data ? data.data.title : "Artikel"} />
......@@ -29,17 +37,53 @@ const Content = props => {
) : status === "error" ? (
<ErrorRetry retry={refetch} />
) : (
<div className="pt-3 pb-5">
<div className="row justify-content-center">
<div className="col-12 col-md-9 col-lg-6">
<h2>{article.title}</h2>
<div className="text-center mb-3">
<img src={article.featured_image} />
</div>
<div dangerouslySetInnerHTML={{ __html: content }} />
</div>
</div>
</div>
<Container className="article">
<Row>
<Col sm={8}>
<Row>
<h3 id="title">
<b className="text-red">{article.title}</b>
</h3>
<img
src={article.featured_image}
alt={article.title}
className="img-fluid rounded mx-auto d-block"
></img>
</Row>
<Row>
<Col className="bg-cream mx-3 py-5 my-5 text-justify">
<div dangerouslySetInnerHTML={{ __html: content }} />
</Col>
</Row>
</Col>
<Col sm={4}>
{statusList === "loading" ? (
<Spinner />
) : statusList === "error" ? (
<ErrorRetry retry={refetchList} />
) : (
dataList.data.results.slice(0, 3).map(newArticle => (
<Link to={"/article/" + newArticle.id} key={newArticle.id}>
<Row className="my-3">
<div className="column">
<div>
<figure>
<img
src={newArticle.featured_image}
alt={newArticle.title}
className="img-fluid rounded mx-auto d-block"
/>
</figure>
<span>{newArticle.title}</span>
</div>
</div>
</Row>
</Link>
))
)}
</Col>
</Row>
</Container>
)}
</Layout>
)
......
import { screen, waitFor } from "@testing-library/react"
import React from "react"
import { renderWithRouter } from "../utils/test-util"
import Article from "./article"
import { getListArtikelEdukasi, getArtikelEdukasi } from "../api"
import { artikelEdukasiFactory } from "../components/artikel-edukasi.factory"
describe(`Article`, () => {
it(`shows article from backend`, async () => {
getArtikelEdukasi.mockResolvedValueOnce({
data: { id: 1, title: "Tes Title", content: "Konten artikel ini" },
})
getListArtikelEdukasi.mockResolvedValueOnce({
data: { results: [artikelEdukasiFactory()] },
})
renderWithRouter(<Article />, { route: "/article/1" })
expect(await screen.findByText("Tes Title")).toBeInTheDocument()
await waitFor(() =>
expect(screen.queryByText("Loading...")).not.toBeInTheDocument()
)
})
})
.column {
.edukasi .column {
margin: 15px 15px 0;
padding: 0;
}
.column:last-child {
.edukasi .column:last-child {
padding-bottom: 60px;
}
.column::after {
.edukasi .column::after {
content: "";
clear: both;
display: block;
}
.column div {
.edukasi .column div {
position: relative;
float: left;
width: 300px;
......@@ -18,10 +18,10 @@
margin: 0 0 0 25px;
padding: 0;
}
.column div:first-child {
.edukasi .column div:first-child {
margin-left: 0;
}
.column div span {
.edukasi .column div span {
position: absolute;
bottom: -70px;
left: 0;
......@@ -38,7 +38,7 @@
transition: 0.3s ease-in-out;
opacity: 0;
}
figure {
.edukasi figure {
width: 300px;
height: 200px;
margin: 0;
......@@ -46,7 +46,7 @@ figure {
background: #fff;
overflow: hidden;
}
figure:hover + span {
.edukasi figure:hover + span {
bottom: -55px;
opacity: 1;
}
import React from "react"
import { Container, Col, Row } from "react-bootstrap"
import Layout from "../components/layout"
import SEO from "../components/seo"
import news_image_1 from "../images/education-1.png"
import news_image_2 from "../images/education-2.jpg"
import news_image_3 from "../images/education-3.jpg"
import "./index.css"
import "../styles/global.css"
import "./edukasi.css"
const Education = () => {
return (
<Layout navbar>
<SEO title="Edukasi - Ini yang perlu diketahui tentang Donor Darah" />
<Container>
<Row>
<Col sm={8}>
<Row>
<h3 id="title">
<b className="text-red">
Ini yang perlu diketahui mengenai golongan darah
</b>
</h3>
<img
src={news_image_1}
className="img-fluid rounded mx-auto d-block"
></img>
</Row>
<Row>
<Col className="bg-cream mx-3 py-5 my-5 text-justify">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat
nulla pariatur. Excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia deserunt mollit anim id est laborum.
</Col>
</Row>
</Col>
<Col sm={4}>
<Row className="my-5">
<div class="column">
<div>
<figure>
<img
src={news_image_2}
className="img-fluid rounded mx-auto d-block"
/>
</figure>
<span>
Syarat dan Ketentuan Donor Darah dari PMI: Batas Usia -
Berat
</span>
</div>
</div>
</Row>
<Row>
<div class="column">
<div>
<figure>
<img
src={news_image_3}
className="img-fluid rounded mx-auto d-block"
/>
</figure>
<span>Donor Darah di Depok</span>
</div>
</div>
</Row>
</Col>
</Row>
</Container>
</Layout>
)
}
export default Education
import Education from "./edukasi"
import "@testing-library/react"
import { render } from "../utils/test-util"
import React from "react"
describe(`Education`, () => {
it(`shows the page`, () => {
const { container } = render(<Education />)
expect(container).toHaveTextContent(
"Ini yang perlu diketahui mengenai golongan darah"
)
})
})
......@@ -13,10 +13,12 @@ import "./kumpulan-artikel.css"
const renderArtikelCard = article => {
return (
<Card>
<Card key={article.id}>
<Card.Img variant="top" src={article.featured_image} />
<Card.Body>
<Card.Title>{article.title}</Card.Title>
<Card.Title>
<Link to={"/article/" + article.id}>{article.title}</Link>
</Card.Title>
<Card.Text className="article">
{article.content
.split(". ")
......
......@@ -3,12 +3,16 @@ import { render } from "../utils/test-util"
import KumpulanArtikel from "./kumpulan-artikel"
import { getListArtikelEdukasi } from "../api"
import { artikelEdukasiFactory } from "../components/artikel-edukasi.factory"
import { screen, fireEvent } from "@testing-library/react"
import { screen, fireEvent, waitFor } from "@testing-library/react"
getListArtikelEdukasi.mockResolvedValue({ data: { count: 0, results: [] } })
describe("Kumpulan Artikel", () => {
it("renders properly", () => {
it("renders properly", async () => {
const { container } = render(<KumpulanArtikel />)
expect(container).toHaveTextContent("Kumpulan Artikel")
await waitFor(() =>
expect(screen.queryByText("Loading...")).not.toBeInTheDocument()
)
})
it("shows artikel from backend", async () => {
......@@ -31,5 +35,8 @@ describe("Kumpulan Artikel", () => {
fireEvent.click(screen.getByText("Halaman selanjutnya kumpulan artikel"))
fireEvent.click(screen.getByText("Halaman sebelumnya kumpulan artikel"))
fireEvent.click(screen.getByText("Halaman 2 kumpulan artikel"))
await waitFor(() =>
expect(screen.queryByText("Loading...")).not.toBeInTheDocument()
)
})
})
import {
createHistory,
createMemorySource,
LocationProvider,
} from "@reach/router"
import { render as renderTestingLibrary } from "@testing-library/react"
import React from "react"
import { AuthProvider } from "../hooks/authenticate"
......@@ -10,3 +15,13 @@ export const renderAuthenticated = component =>
renderTestingLibrary(
<AuthenticatedProvider>{component}</AuthenticatedProvider>
)
export const renderWithRouter = (
ui,
{ route = "/", history = createHistory(createMemorySource(route)) } = {}
) => {
return {
...render(<LocationProvider history={history}>{ui}</LocationProvider>),
history,
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment