mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-05 09:48:44 +00:00
updates to cards
This commit is contained in:
1 parent
4acac21a9e
commit
f6b58f1099
9 files changed
+172
-73
No files matched your search
Binary file not shown.
|
After Width: | Height: | Size: 82 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 93 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 62 KiB |
@@ -1,16 +1,30 @@
|
||||
import React from "react";
|
||||
import { useHistory } from "react-router-dom";
|
||||
import Card from "../Card";
|
||||
import AudioPlayer from "components/common/AudioPlayer";
|
||||
|
||||
interface AudioCardProps {
|
||||
data: any;
|
||||
to: string;
|
||||
}
|
||||
|
||||
export default function AudioCard({ data }: AudioCardProps) {
|
||||
export default function AudioCard({ data, to }: AudioCardProps) {
|
||||
const history = useHistory();
|
||||
|
||||
const handleCardClick = () => {
|
||||
history.push(to);
|
||||
};
|
||||
|
||||
const handleInnerClick = (event: any) => {
|
||||
event.stopPropagation();
|
||||
};
|
||||
|
||||
return (
|
||||
<Card padding={true}>
|
||||
<h4>{data.weight_name}</h4>
|
||||
<AudioPlayer src={data.public_bucket_path} />
|
||||
<Card padding={true} onClick={handleCardClick}>
|
||||
<h6 className="fw-semibold text-white mb-3">{data.weight_name}</h6>
|
||||
<div onClick={handleInnerClick}>
|
||||
<AudioPlayer src={data.public_bucket_path} />
|
||||
</div>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
@@ -5,4 +5,53 @@
|
||||
border: 1px solid $panel-inner-border;
|
||||
border-radius: 0.5rem;
|
||||
overflow: hidden;
|
||||
transition: 0.2s;
|
||||
position: relative;
|
||||
|
||||
.card-img {
|
||||
width: 100%;
|
||||
transition: 0.2s;
|
||||
object-fit: cover;
|
||||
object-position: center;
|
||||
}
|
||||
|
||||
.card-image-overlay {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.card-image-gradient {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 40%;
|
||||
background: linear-gradient(180deg, transparent, black);
|
||||
}
|
||||
|
||||
.card-image-overlay-text {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
padding: 1rem;
|
||||
color: $white;
|
||||
font-weight: 500;
|
||||
font-size: 1.2rem;
|
||||
text-shadow: 0 0 10px black;
|
||||
}
|
||||
|
||||
&.card-clickable {
|
||||
&:hover {
|
||||
background-color: lighten($panel-inner, 3%);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&:hover > .card-img {
|
||||
transform: scale(1.04);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,8 +4,18 @@ import "./Card.scss";
|
||||
interface CardProps {
|
||||
padding?: boolean;
|
||||
children?: React.ReactNode;
|
||||
onClick?: () => void;
|
||||
}
|
||||
|
||||
export default function Card({ padding, children }: CardProps) {
|
||||
return <div className={`card ${padding && "p-3"}`}>{children}</div>;
|
||||
export default function Card({ padding, children, onClick }: CardProps) {
|
||||
return (
|
||||
<div
|
||||
className={`card ${padding ? "p-3" : ""} ${
|
||||
onClick ? "card-clickable" : ""
|
||||
}`}
|
||||
onClick={onClick}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,18 +1,34 @@
|
||||
import React from "react";
|
||||
import { useHistory } from "react-router-dom";
|
||||
import Card from "../Card";
|
||||
|
||||
interface ImageCardProps {
|
||||
data: any;
|
||||
to: string;
|
||||
}
|
||||
|
||||
export default function ImageCard({ data }: ImageCardProps) {
|
||||
export default function ImageCard({ data, to }: ImageCardProps) {
|
||||
const history = useHistory();
|
||||
|
||||
const handleCardClick = () => {
|
||||
history.push(to);
|
||||
};
|
||||
|
||||
// const handleInnerClick = (event: any) => {
|
||||
// event.stopPropagation();
|
||||
// };
|
||||
|
||||
return (
|
||||
<Card padding={false}>
|
||||
<Card padding={false} onClick={handleCardClick}>
|
||||
<img
|
||||
src={data.public_bucket_path}
|
||||
alt={data.weight_name}
|
||||
className="img-fluid"
|
||||
className="card-img"
|
||||
/>
|
||||
<div className="card-image-overlay">
|
||||
<div className="card-image-gradient"></div>
|
||||
<div className="card-image-overlay-text">{data.weight_name}</div>
|
||||
</div>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
@@ -4,56 +4,66 @@ import MasonryGrid from "components/common/MasonryGrid/MasonryGrid";
|
||||
import mockData from "./mockData";
|
||||
import AudioCard from "components/common/Card/AudioCard";
|
||||
import ImageCard from "components/common/Card/ImageCard";
|
||||
import InfiniteScroll from "react-infinite-scroll-component";
|
||||
// import InfiniteScroll from "react-infinite-scroll-component";
|
||||
import Panel from "components/common/Panel";
|
||||
import { Select } from "components/common/Inputs/Inputs";
|
||||
import { faFilter } from "@fortawesome/pro-solid-svg-icons";
|
||||
|
||||
export default function MediaTab() {
|
||||
const [data, setData] = useState(mockData); // State to hold your data
|
||||
const [hasMore, setHasMore] = useState(true);
|
||||
const [data, setData] = useState(mockData);
|
||||
// const [hasMore, setHasMore] = useState(true);
|
||||
|
||||
const fetchData = () => {
|
||||
setTimeout(() => {
|
||||
setData((prevData) => [...prevData, ...mockData]);
|
||||
setHasMore(false);
|
||||
}, 1500);
|
||||
};
|
||||
// const fetchData = () => {
|
||||
// setTimeout(() => {
|
||||
// setData((prevData) => [...prevData, ...mockData]);
|
||||
// setHasMore(false);
|
||||
// }, 1500);
|
||||
// };
|
||||
|
||||
const options = [
|
||||
{ value: "all", label: "All Media" },
|
||||
{ value: "images", label: "Images" },
|
||||
{ value: "audio", label: "Audio" },
|
||||
{ value: "video", label: "Video" },
|
||||
];
|
||||
|
||||
return (
|
||||
<Panel clear={true} padding={true}>
|
||||
<InfiniteScroll
|
||||
dataLength={data.length}
|
||||
next={fetchData}
|
||||
hasMore={hasMore}
|
||||
loader={<h4>Loading...</h4>}
|
||||
className="overflow-hidden"
|
||||
>
|
||||
<MasonryGrid>
|
||||
{data.map((data, index) => {
|
||||
let card;
|
||||
switch (data.media_type) {
|
||||
case "audio":
|
||||
card = <AudioCard key={index} data={data} />;
|
||||
break;
|
||||
case "image":
|
||||
card = <ImageCard key={index} data={data} />;
|
||||
break;
|
||||
case "video":
|
||||
card = <>test</>;
|
||||
break;
|
||||
default:
|
||||
card = <div key={index}>Unsupported media type</div>;
|
||||
}
|
||||
return (
|
||||
<div
|
||||
key={index}
|
||||
className="col-12 col-sm-6 col-lg-4 col-xl-3 grid-item"
|
||||
>
|
||||
{card}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</MasonryGrid>
|
||||
</InfiniteScroll>
|
||||
<div className="d-flex mb-3">
|
||||
<Select
|
||||
icon={faFilter}
|
||||
options={options}
|
||||
defaultValue={options[0]}
|
||||
isSearchable={false}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<MasonryGrid>
|
||||
{data.map((data, index) => {
|
||||
let card;
|
||||
switch (data.media_type) {
|
||||
case "audio":
|
||||
card = <AudioCard key={index} data={data} to="/" />;
|
||||
break;
|
||||
case "image":
|
||||
card = <ImageCard key={index} data={data} to="/" />;
|
||||
break;
|
||||
case "video":
|
||||
card = <>test</>;
|
||||
break;
|
||||
default:
|
||||
card = <div key={index}>Unsupported media type</div>;
|
||||
}
|
||||
return (
|
||||
<div
|
||||
key={index}
|
||||
className="col-12 col-sm-6 col-xl-4 col-xxl-3 grid-item"
|
||||
>
|
||||
{card}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</MasonryGrid>
|
||||
</Panel>
|
||||
);
|
||||
}
|
||||
@@ -17,15 +17,15 @@ const mockData = [
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
weight_name: "3",
|
||||
weight_name: "Ronaldo",
|
||||
media_type: "audio",
|
||||
public_bucket_path: "/path/to/image.jpg",
|
||||
public_bucket_path: "/path/to/audio.mp3",
|
||||
favorites: 200,
|
||||
liked: false,
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
weight_name: "4",
|
||||
weight_name: "Messi",
|
||||
media_type: "audio",
|
||||
public_bucket_path: "/path/to/audio.mp3",
|
||||
favorites: 150,
|
||||
@@ -33,9 +33,9 @@ const mockData = [
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
weight_name: "5",
|
||||
weight_name: "Ash Ketchum",
|
||||
media_type: "image",
|
||||
public_bucket_path: "/images/dummy-image.jpg",
|
||||
public_bucket_path: "/images/dummy-image-2.jpg",
|
||||
favorites: 200,
|
||||
liked: false,
|
||||
},
|
||||
@@ -48,34 +48,34 @@ const mockData = [
|
||||
liked: false,
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
weight_name: "4",
|
||||
id: 7,
|
||||
weight_name: "Son Goku",
|
||||
media_type: "audio",
|
||||
public_bucket_path: "/path/to/audio.mp3",
|
||||
favorites: 150,
|
||||
liked: true,
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
weight_name: "4",
|
||||
id: 8,
|
||||
weight_name: "Image Test",
|
||||
media_type: "image",
|
||||
public_bucket_path: "/images/dummy-image-3.jpg",
|
||||
favorites: 150,
|
||||
liked: true,
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
weight_name: "Monokuma",
|
||||
media_type: "audio",
|
||||
public_bucket_path: "/path/to/audio.mp3",
|
||||
favorites: 150,
|
||||
liked: true,
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
weight_name: "4",
|
||||
media_type: "audio",
|
||||
public_bucket_path: "/path/to/audio.mp3",
|
||||
favorites: 150,
|
||||
liked: true,
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
weight_name: "4",
|
||||
media_type: "audio",
|
||||
public_bucket_path: "/path/to/audio.mp3",
|
||||
id: 10,
|
||||
weight_name: "Image Test",
|
||||
media_type: "image",
|
||||
public_bucket_path: "/images/dummy-image-4.jpg",
|
||||
favorites: 150,
|
||||
liked: true,
|
||||
},
|
||||
|
||||
Reference in new issue
Block a user