Skip to content
This repository has been archived by the owner on Jul 3, 2023. It is now read-only.

Commit

Permalink
Staging to Main (#94)
Browse files Browse the repository at this point in the history
* Patch - Dokum (#93)

* Add dokum page

* Integerate dokum page backend

* Add dokum swiper thumbs

* Add style for active dokum

* Add back button

* Improve styling

* Improve style

* Add download functionality

* Add video dokum

* Fix dokum api slug search & handle empty video

* Add dokumentasi lainnya section

* Make share button functionable on dokum page

* Fix photo error download

* Fix error download video

* Add decoration

* Refactor dokum lainnya

Co-authored-by: marcellinuselbert11 <[email protected]>
Co-authored-by: Marcellinus Elbert <[email protected]>

* Fix padding on dokum lainnya section

* Make sharelink more versatile to any link routing

* Change share click handler

* Make picture clickable on dokum card

Co-authored-by: Naufal Weise <[email protected]>
Co-authored-by: Marcellinus Elbert <[email protected]>
  • Loading branch information
3 people authored Oct 2, 2022
1 parent 6cc5b9f commit 8ec1baf
Show file tree
Hide file tree
Showing 15 changed files with 561 additions and 138 deletions.
102 changes: 102 additions & 0 deletions components/card/DokumentasiCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import Link from "next/link";
import {
Card,
BodyResponsive,
HeaderResponsive,
useWindowSize,
ShareLinkToClipboard,
} from "@components";
import { Dokumentasi } from "@models";
import { PhotographIcon, PlayIcon } from "@heroicons/react/outline";

type DokumentasiCardProps = {
dokumentasi: Dokumentasi;
index: number;
className?: string;
};

export const DokumentasiCard = ({
dokumentasi,
index,
className,
}: DokumentasiCardProps) => {
const windowSize = useWindowSize();
const { width } = useWindowSize();

const truncate = (input: string) => {
const words = width >= 1280 ? 50 : 35;
return input.length > words ? `${input.substring(0, words)}...` : input;
};

return (
<Card
preset="light"
className={`w-full ${className} desktop:h-[380px] tablet:h-[280px] mobile:h-[250px] desktop:p-4 tablet:p-[14px] mobile:p-4 relative`}
key={index}
>
<Link href={`/dokumentasi/${dokumentasi.slug}`}>
<a>
<div
className="desktop:h-36 tablet:h-[40%] mobile:h-[55%] w-[90%] bg-cover bg-center opacity-80 absolute desktop:left-[15px] tablet:left-[11px] rounded-[9px] "
style={{
backgroundImage: `url(${dokumentasi.photoUrls[0]})`,
}}
/>
<div className="desktop:pt-40 tablet:pt-32 mobile:pt-40">
<BodyResponsive
windowSize={windowSize}
preset="p2"
presetTablet="p2"
presetDesktop="p2"
className="text-denim-dark font-bold "
>
{dokumentasi.date}
</BodyResponsive>
<HeaderResponsive
windowSize={windowSize}
preset="h7"
presetTablet="h6"
presetDesktop="h5"
className="tablet:block mobile:hidden"
>
{truncate(dokumentasi.title)}
</HeaderResponsive>
</div>{" "}
</a>
</Link>
<div className="mt-3 flex w-[85%] absolute justify-between bottom-4">
<div className="flex items-center desktop:gap-2 tablet:gap-0.5 mobile:gap-2">
<BodyResponsive
windowSize={windowSize}
preset="p3"
presetTablet="p2"
presetDesktop="p2"
className="text-cerulean font-bold "
>
{dokumentasi.photoUrls.length}
</BodyResponsive>
<PhotographIcon className="w-5 h-5 stroke-cerulean" />
</div>
<div className="flex items-center desktop:gap-2 tablet:gap-0.5 mobile:gap-2">
<BodyResponsive
windowSize={windowSize}
preset="p3"
presetTablet="p2"
presetDesktop="p2"
className="text-cerulean font-bold "
>
{dokumentasi.videoUrls.length}
</BodyResponsive>
<PlayIcon className="w-5 h-5 stroke-cerulean" />
</div>
<div className="flex items-center desktop:gap-2 tablet:gap-0.5 mobile:gap-2">
{/* <ShareIcon className="w-5 h-5 stroke-denim-dark" /> */}
<ShareLinkToClipboard
className="right-0 top-1"
link={"dokumentasi/" + dokumentasi.slug}
/>
</div>
</div>
</Card>
);
};
1 change: 1 addition & 0 deletions components/card/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from "./Card";
export * from "./DonationCard";
export * from "./DokumentasiCard"
2 changes: 1 addition & 1 deletion components/modules/artikel/ArtikelArtikelLainnya.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ export const ArtikelArtikelLainnya = ({
: "absolute bottom-3 right-0 w-6"
: "right-24"
}
link={article.slug}
link={"article/" + article.slug}
/>
<Link href={"/artikel/" + article?.slug}>
<div className={width >= 1280 && !bodyPage ? "pt-6" : ""}>
Expand Down
2 changes: 1 addition & 1 deletion components/modules/artikel/ArtikelTerbaru.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ export const ArtikelTerbaru = ({
? "absolute bottom-3 right-20 desktop:bottom-[21px] desktop:right-10"
: "absolute bottom-3 right-3"
}
link={article.slug}
link={"article/" + article.slug}
/>
</Card>
</div>
Expand Down
6 changes: 3 additions & 3 deletions components/modules/artikel/ShareLinkToClipboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Toast } from "@components/toast";

type ShareLinkToClipboardProps = {
className?: string;
link?: any;
link: string;
children?: React.ReactNode;
};

Expand All @@ -21,7 +21,7 @@ export const ShareLinkToClipboard = ({
});

const shareClickHandler = () => {
navigator.clipboard.writeText(WEBSITE_URL + "/artikel/" + link);
navigator.clipboard.writeText(WEBSITE_URL + "/" + link);
setIsCopied(true);
successToast();
setTimeout(() => setIsCopied(false), 6000);
Expand All @@ -40,7 +40,7 @@ export const ShareLinkToClipboard = ({
<ClipboardCheckIcon
className={className + " w-5 absolute bottom-4 hover:cursor-pointer"}
onClick={() => {
navigator.clipboard.writeText(WEBSITE_URL + "/artikel/" + link);
navigator.clipboard.writeText(WEBSITE_URL + "/" + link);
}}
/>
);
Expand Down
91 changes: 6 additions & 85 deletions components/modules/dokumentasi/DokumentasiList.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import {
HeaderResponsive,
useWindowSize,
Card,
BodyResponsive,
Button,
DokumentasiCard,
} from "@components";
import { PhotographIcon, PlayIcon, ShareIcon } from "@heroicons/react/outline";
import { Dokumentasi } from "@models";
import Link from "next/link";
import { useEffect, useState } from "react";
import { useState } from "react";

type DokumentasiListProps = {
dokumentasi: Dokumentasi[] | undefined;
Expand All @@ -20,11 +17,6 @@ export const DokumentasiList = ({ dokumentasi }: DokumentasiListProps) => {
const [dokumentasiAmount, setDokumentasiAmount] = useState<number>(0);
const [isClicked, setIsClicked] = useState(false);

const truncate = (input: string) => {
const words = width >= 1280 ? 50 : 35;
return input.length > words ? `${input.substring(0, words)}...` : input;
};

const dokumentasiSliced = dokumentasi?.slice(
0,
isClicked ? dokumentasiAmount + initialAmount : initialAmount
Expand Down Expand Up @@ -52,81 +44,10 @@ export const DokumentasiList = ({ dokumentasi }: DokumentasiListProps) => {
</HeaderResponsive>
</div>
<div className="desktop:mt-12 tablet:mt-7 mobile:mt-4 grid desktop:grid-cols-4 tablet:grid-cols-3 mobile:grid-cols-1 desktop:gap-6 tablet:gap-4 mobile:gap-4">
{dokumentasiSliced?.map((dok: any, index: number) => (
<Link href={`/dokumentasi/${dok.slug}`} key={index}>
<a>
<Card
preset="light"
className="w-full desktop:h-[380px] tablet:h-[280px] mobile:h-[250px] desktop:p-4 tablet:p-[14px] mobile:p-4 relative cursor-pointer"
key={index}
>
<div
className="desktop:h-36 tablet:h-[40%] mobile:h-[55%] w-[90%] bg-cover bg-center opacity-80 absolute desktop:left-[15px] tablet:left-[11px] rounded-[9px] "
style={{
backgroundImage: `url(${dok.photoUrls[0]})`,
}}
/>
<div className="desktop:pt-40 tablet:pt-32 mobile:pt-40">
<BodyResponsive
windowSize={windowSize}
preset="p2"
presetTablet="p2"
presetDesktop="p2"
className="text-denim-dark font-bold "
>
{dok.date}
</BodyResponsive>
<HeaderResponsive
windowSize={windowSize}
preset="h7"
presetTablet="h6"
presetDesktop="h5"
className="tablet:block mobile:hidden"
>
{truncate(dok.title)}
</HeaderResponsive>
</div>
<div className="mt-3 flex w-[85%] absolute justify-between bottom-4">
<div className="flex items-center desktop:gap-2 tablet:gap-0.5 mobile:gap-2">
<BodyResponsive
windowSize={windowSize}
preset="p3"
presetTablet="p2"
presetDesktop="p2"
className="text-cerulean font-bold "
>
{dok.photoUrls.length}
</BodyResponsive>
<PhotographIcon className="w-5 h-5 stroke-cerulean" />
</div>
<div className="flex items-center desktop:gap-2 tablet:gap-0.5 mobile:gap-2">
<BodyResponsive
windowSize={windowSize}
preset="p3"
presetTablet="p2"
presetDesktop="p2"
className="text-cerulean font-bold "
>
{dok.videoUrls.length}
</BodyResponsive>
<PlayIcon className="w-5 h-5 stroke-cerulean" />
</div>
<div className="flex items-center desktop:gap-2 tablet:gap-0.5 mobile:gap-2">
<ShareIcon className="w-5 h-5 stroke-denim-dark" />
<BodyResponsive
windowSize={windowSize}
preset="p3"
presetTablet="p2"
presetDesktop="p2"
className="text-denim-dark font-bold "
>
Bagikan
</BodyResponsive>
</div>
</div>
</Card>
</a>
</Link>
{dokumentasiSliced?.map((dok: Dokumentasi, index: number) => (
<div key={index}>
<DokumentasiCard dokumentasi={dok} index={index} />
</div>
))}
</div>
<div className="flex justify-center tablet:mt-8 mobile:mt-4">
Expand Down
30 changes: 24 additions & 6 deletions next.config.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,35 @@
const withReactSvg = require("next-react-svg");
const path = require("path");

const apiUrl = new URL(process.env.NEXT_PUBLIC_API_STRAPI);

module.exports = withReactSvg({
images: {
domains: ["localhost", "api.depokkita.com"],
},
include: path.resolve(__dirname, "public/assets"),
images: {
domains: ["api.depokkita.com", "localhost", "res.cloudinary.com"],
},
experimental: {
esmExternals: false,
},
webpack(config, options) {
return config;
},
images: {
domains: [
apiUrl.host,
"localhost",
"api.depokkita.com",
"res.cloudinary.com",
],
},
async headers() {
return [
{
source: "/:path*",
headers: [
{
key: "Content-Security-Policy",
value: `frame-ancestors 'self' https://api.depokkita.com;`,
},
],
},
];
},
});
44 changes: 24 additions & 20 deletions pages/api/dokumentasi/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,35 @@ import type { NextApiRequest, NextApiResponse } from "next";
import axios from "axios";
import { Dokumentasi } from "@models";

export default function handler(_: NextApiRequest, res: NextApiResponse) {
const parseDokumentasi = (dokumentasiRaw: any): Dokumentasi =>
({
slug: dokumentasiRaw.attributes.slug,
title: dokumentasiRaw.attributes.title,
date: dokumentasiRaw.attributes.date,
photoUrls: dokumentasiRaw.attributes.photos.data.map(
(photo: any) => photo.attributes.url
),
videoUrls:
dokumentasiRaw.attributes.videos.data?.map(
(video: any) => video.attributes.url
) ?? [],
} as Dokumentasi);

export default function handler(req: NextApiRequest, res: NextApiResponse) {
axios
.get(
`${process.env.NEXT_PUBLIC_API_STRAPI}/api/dokumentasis?populate=photos,videos`
`${process.env.NEXT_PUBLIC_API_STRAPI}/api/dokumentasis/?populate=photos,videos`,
{
params: {
populate: ["photos", "videos"],
"filters[slug][$eq]": req.query.slug,
},
}
)
.then((response) => {
try {
res.status(200).json(
response.data.data.map(
(dokumentasi: any) =>
({
slug: dokumentasi.attributes.slug,
title: dokumentasi.attributes.title,
date: dokumentasi.attributes.date,
photoUrls: dokumentasi.attributes.photos.data.map(
(photo: any) =>
process.env.NEXT_PUBLIC_API_STRAPI + photo.attributes.url
),
videoUrls: dokumentasi.attributes.videos.data.map(
(video: any) =>
process.env.NEXT_PUBLIC_API_STRAPI + video.attributes.url
),
} as Dokumentasi)
)
);
let parsedData = response.data.data.map(parseDokumentasi);
res.status(200).json(parsedData);
} catch (e) {
console.log(e);
}
Expand Down
Loading

0 comments on commit 8ec1baf

Please sign in to comment.