Skip to content

Instantly share code, notes, and snippets.

@ahmetskilinc
Created May 10, 2024 12:49
Show Gist options
  • Save ahmetskilinc/be0cf5b29b266c01c452c6ea486a1f8b to your computer and use it in GitHub Desktop.
Save ahmetskilinc/be0cf5b29b266c01c452c6ea486a1f8b to your computer and use it in GitHub Desktop.
MediaList payload 3.x
.SortingHeader {
display: flex;
overflow-x: scroll;
gap: 18px;
align-items: center;
}
.MediaGrid {
display: grid;
gap: 1.5rem;
grid-template-columns: repeat(2, minmax(0, 1fr));
@media (min-width: 520px) {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
@media (min-width: 1024px) {
grid-template-columns: repeat(4, minmax(0, 1fr));
}
@media (min-width: 1280px) {
grid-template-columns: repeat(6, minmax(0, 1fr));
}
}
.MediaGridCard {
outline-style: solid;
outline-width: 2px;
border-radius: 8px !important;
outline-color: rgb(47, 47, 47);
text-decoration: none;
text-align: left;
position: relative;
> a > span > span {
display: flex !important;
flex-direction: column;
justify-content: space-between;
}
}
.MediaGridCard:hover {
.MediaCardMeta {
background-color: rgb(47, 47, 47);
}
}
.MediaGridCardSelect {
position: absolute;
top: 8px;
left: 8px;
z-index: 10;
}
.MediaGridCardMedia {
object-fit: contain;
aspect-ratio: 1/1;
width: 100%;
}
.MediaCardMeta {
padding: 12px;
background-color: rgb(31, 31, 31);
display: flex;
flex-direction: column;
flex-grow: 1;
flex-shrink: 0;
}
.MediaGridCardTitle {
width: 100%;
font-weight: 500;
overflow-wrap: anywhere;
text-decoration: underline;
margin-bottom: 0;
}
.MediaGridCardAlt {
width: 100%;
font-weight: 300;
overflow-wrap: anywhere;
text-decoration: none;
margin-bottom: 0;
opacity: 0.5;
}
import React, { Fragment } from "react";
// import { useWindowInfo } from "@payloadcms/ui/elements/WindowInfo";
import { DeleteMany } from "@payloadcms/ui/elements/DeleteMany";
import { EditMany } from "@payloadcms/ui/elements/EditMany";
import { Gutter } from "@payloadcms/ui/elements/Gutter";
import { ListControls } from "@payloadcms/ui/elements/ListControls";
import { ListSelection } from "@payloadcms/ui/elements/ListSelection";
import { SortColumn } from "@payloadcms/ui/elements/SortColumn";
import { Pagination } from "@payloadcms/ui/elements/Pagination";
import { PerPage } from "@payloadcms/ui/elements/PerPage";
import { Pill } from "@payloadcms/ui/elements/Pill";
import { PublishMany } from "@payloadcms/ui/elements/PublishMany";
import { UnpublishMany } from "@payloadcms/ui/elements/UnpublishMany";
import { ViewDescription } from "@payloadcms/ui/elements/ViewDescription";
import { Button } from "@payloadcms/ui/elements/Button";
import { SelectionProvider } from "@payloadcms/ui/providers/Selection";
import { useConfig } from "@payloadcms/ui/providers/Config";
import { useTranslation } from "@payloadcms/ui/providers/Translation";
import { formatDate } from "@payloadcms/ui/utilities/formatDate";
import { SelectRow } from "@payloadcms/ui/elements/SelectRow";
import { SelectAll } from "@payloadcms/ui/elements/SelectAll";
// import Meta from "payload/dist/admin/components/utilities/Meta";
// import type { Props } from "payload/dist/admin/components/views/collections/List/types";
import classes from "./MediaList.module.scss";
import { Media } from "@/payload-types";
const baseClass = "collection-list";
export const MediaList = (props: any) => {
const {
data,
// collection: {
// labels: { plural: pluralLabel, singular: singularLabel },
// },
limit,
collection,
handlePageChange,
handlePerPageChange,
handleSearchChange,
handleSortChange,
handleWhereChange,
hasCreatePermission,
modifySearchParams,
newDocumentURL,
resetParams,
titleField,
customHeader,
} = props;
// const {
// breakpoints: { s: smallBreak },
// } = useWindowInfo();
// const { i18n, t } = useTranslation();
const {
admin: { dateFormat },
routes: { admin: adminRoute },
} = useConfig();
return (
<div className="collection-list">
{/* <Meta title={getTranslation(collection.labels.plural, i18n)} /> */}
<SelectionProvider docs={data.docs} totalDocs={data.totalDocs}>
<Gutter className={`${baseClass}__wrap`}>
<header className={`${baseClass}__header`}>
{customHeader && customHeader}
{!customHeader && (
<Fragment>
<h1>Media</h1>
{hasCreatePermission && (
<Pill
// aria-label={t("createNewLabel", { label: getTranslation(singularLabel, i18n) })}
aria-label={""}
to={newDocumentURL}
>
{/* {t("createNew")} */}
Create new
</Pill>
)}
{/* {!smallBreak && <ListSelection label={getTranslation(pluralLabel, i18n)} />} */}
{/* {!smallBreak && <ListSelection label={""} />} */}
</Fragment>
)}
</header>
{/* <ListControls
collection={collection}
handleSearchChange={handleSearchChange}
handleSortChange={handleSortChange}
handleWhereChange={handleWhereChange}
modifySearchQuery={modifySearchParams}
resetParams={resetParams}
titleField={titleField}
enableColumns={false}
/> */}
<div className={classes.SortingHeader}>
<SelectAll />
{/* <SortColumn label="File Name" name="filename" />
<SortColumn label="Alt Tag" name="alt" />
<SortColumn label="Created At" name="createdAt" />
<SortColumn label="Updated At" name="updatedAt" /> */}
</div>
<div className={classes.MediaGrid}>
{props.data.docs
? props.data.docs.map((doc: Media) => (
<Button
key={doc.id}
className={classes.MediaGridCard}
el={"link"}
buttonStyle="none"
to={`${adminRoute}/collections/media/${doc.id}`}
>
{/* <div className={classes.MediaGridCardSelect}>
<SelectRow id={doc.id} />
</div> */}
{doc.mimeType?.includes("image") ? (
doc.mimeType.includes("svg") ? (
<img src={doc.url!} className={classes.MediaGridCardMedia} />
) : null
) : (
// <img src={doc.sizes.optimised.url} className={classes.MediaGridCardMedia} />
<video
src={doc.url!}
autoPlay
muted
loop
className={classes.MediaGridCardMedia}
/>
)}
<div className={classes.MediaCardMeta}>
<p className={classes.MediaGridCardTitle}>{doc.filename}</p>
<p className={classes.MediaGridCardAlt}>{doc.alt || "<No Alt Text>"}</p>
{/* <p className={classes.MediaGridCardAlt}>
{formatDate(doc.updatedAt, dateFormat, i18n?.language)}
</p> */}
<p className={classes.MediaGridCardAlt}>
{/* {formatDate(doc.createdAt, dateFormat, i18n?.language)} */}
{/* {formatDate(doc.createdAt, dateFormat, i18n?.language)} */}
</p>
</div>
</Button>
))
: null}
</div>
{data.docs && data.docs.length > 0 && (
<div className={`${baseClass}__page-controls`}>
<Pagination
// disableHistoryChange={modifySearchParams === false}
hasNextPage={data.hasNextPage}
hasPrevPage={data.hasPrevPage}
limit={data.limit}
nextPage={data.nextPage}
numberOfNeighbors={1}
onChange={handlePageChange}
page={data.page}
prevPage={data.prevPage}
totalPages={data.totalPages}
/>
{data?.totalDocs > 0 && (
<Fragment>
<div className={`${baseClass}__page-info`}>
{data.page * data.limit - (data.limit - 1)}-
{data.totalPages > 1 && data.totalPages !== data.page
? data.limit * data.page
: data.totalDocs}{" "}
{/* {t("of")} */}
of {data.totalDocs}
</div>
<PerPage
handleChange={handlePerPageChange}
limit={limit}
limits={collection?.admin?.pagination?.limits}
// modifySearchParams={modifySearchParams}
resetPage={data.totalDocs <= data.pagingCounter}
/>
{/* {smallBreak && (
<div className={`${baseClass}__list-selection`}>
<Fragment>
<ListSelection label={getTranslation(collection.labels.plural, i18n)} />
<div className={`${baseClass}__list-selection-actions`}>
<EditMany collection={collection} resetParams={resetParams} />
<PublishMany collection={collection} resetParams={resetParams} />
<UnpublishMany collection={collection} resetParams={resetParams} />
<DeleteMany collection={collection} resetParams={resetParams} />
</div>
</Fragment>
</div>
)} */}
</Fragment>
)}
</div>
)}
</Gutter>
</SelectionProvider>
</div>
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment