mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-09 03:21:23 +00:00
prelaunch landing init
This commit is contained in:
1 parent
b5ce95b592
commit
505c36784b
2 files changed
+247
-42
No files matched your search
+90
-27
@@ -2,42 +2,30 @@
|
||||
|
||||
.grid-container {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(6, 1fr);
|
||||
grid-template-rows: repeat(5, calc(100vw / 6 * 9 / 16));
|
||||
grid-template-columns: repeat(7, 1fr);
|
||||
grid-template-rows: repeat(7, calc(100vw / 7 * (9 / 16)));
|
||||
gap: 16px;
|
||||
padding: 10px;
|
||||
padding: 16px;
|
||||
position: relative;
|
||||
|
||||
.logo {
|
||||
position: absolute;
|
||||
margin-left: 4%;
|
||||
top: 46%;
|
||||
width: 40%;
|
||||
@media (max-width: 992px) {
|
||||
grid-template-columns: repeat(5, 1fr);
|
||||
grid-template-rows: repeat(5, calc(100vw / 5 * (9 / 16)));
|
||||
gap: 16px;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.waitlist-button {
|
||||
position: absolute;
|
||||
margin-left: 4%;
|
||||
top: 63%;
|
||||
padding: 1%;
|
||||
width: 25%;
|
||||
font-size: 20px;
|
||||
font-weight: 500;
|
||||
color: #fff;
|
||||
background-color: $primary;
|
||||
border-radius: 50px;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
|
||||
&:hover {
|
||||
background-color: lighten($primary, 5%);
|
||||
}
|
||||
@media (max-width: 768px) {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
grid-template-rows: repeat(3, calc(100vw / 3 * (9 / 16)));
|
||||
gap: 12px;
|
||||
padding: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.grid-item {
|
||||
background-color: #ccc;
|
||||
position: relative;
|
||||
background-color: rgba($white, 0.06);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -45,10 +33,85 @@
|
||||
overflow: hidden;
|
||||
transition: transform 0.2s;
|
||||
pointer-events: all;
|
||||
border: none;
|
||||
|
||||
&:hover {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
&.double-grid {
|
||||
grid-column: span 2;
|
||||
}
|
||||
|
||||
&.triple-grid {
|
||||
grid-column: span 3;
|
||||
}
|
||||
|
||||
&.grid-item-custom {
|
||||
overflow: visible;
|
||||
position: relative;
|
||||
|
||||
&:hover {
|
||||
transform: none;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.logo {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
margin-left: 20%;
|
||||
margin-top: 10%;
|
||||
width: 270%;
|
||||
cursor: default;
|
||||
|
||||
@media (max-width: 992px) {
|
||||
margin-left: 22%;
|
||||
margin-top: 15%;
|
||||
}
|
||||
}
|
||||
|
||||
.waitlist-button {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
margin-left: 10%;
|
||||
margin-top: 4%;
|
||||
font-size: 20px;
|
||||
font-weight: 500;
|
||||
color: #fff;
|
||||
background-color: $primary;
|
||||
border-radius: 50px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
width: 84%;
|
||||
padding: 2.5%;
|
||||
border: 4px solid lighten($primary, 12%);
|
||||
box-shadow: 0 0 15px rgba(255, 255, 255, 0.7); // Soft white glow
|
||||
animation: glow 1.5s infinite alternate;
|
||||
|
||||
&:hover {
|
||||
background-color: lighten($primary, 5%);
|
||||
}
|
||||
|
||||
@media (max-width: 992px) {
|
||||
margin-left: 8%;
|
||||
margin-top: 2%;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes glow {
|
||||
from {
|
||||
box-shadow: 0 0 50px rgba(255, 170, 168, 0.25);
|
||||
}
|
||||
to {
|
||||
box-shadow: 0 0 25px rgba(255, 170, 168, 0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.grid-item.blank {
|
||||
|
||||
+157
-15
@@ -1,19 +1,169 @@
|
||||
// Grid.tsx
|
||||
import React from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import "./PrelaunchLanding.scss";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { faArrowRight } from "@fortawesome/pro-solid-svg-icons";
|
||||
import { BucketConfig } from "@storyteller/components/src/api/BucketConfig";
|
||||
import { set } from "date-fns";
|
||||
|
||||
interface MediaItem {
|
||||
token: string;
|
||||
public_bucket_path: string;
|
||||
maybe_creator: {
|
||||
username: string;
|
||||
};
|
||||
}
|
||||
|
||||
const PrelaunchLanding: React.FC = () => {
|
||||
const totalGrids = 30;
|
||||
const blankGrids = [13, 14, 15, 19, 20];
|
||||
const totalGrids = 63;
|
||||
const [mediaItems, setMediaItems] = useState<MediaItem[]>([]);
|
||||
const [blankGrids, setBlankGrids] = useState<number[]>([15, 16, 17, 22, 23]);
|
||||
const [screenSize, setScreenSize] = useState("lg");
|
||||
|
||||
useEffect(() => {
|
||||
fetchMediaItems();
|
||||
updateGridsForScreenSize();
|
||||
window.addEventListener("resize", updateGridsForScreenSize);
|
||||
return () => window.removeEventListener("resize", updateGridsForScreenSize);
|
||||
}, []);
|
||||
|
||||
const updateGridsForScreenSize = () => {
|
||||
const screenWidth = window.innerWidth;
|
||||
if (screenWidth < 768) {
|
||||
setBlankGrids([7, 8, 9, 10, 11, 12]);
|
||||
setScreenSize("sm");
|
||||
} else if (screenWidth < 992) {
|
||||
setBlankGrids([12, 13, 14, 17, 18, 19]);
|
||||
setScreenSize("md");
|
||||
} else {
|
||||
setBlankGrids([15, 16, 17, 22, 23]);
|
||||
setScreenSize("lg");
|
||||
}
|
||||
};
|
||||
|
||||
const getCustomGridItemIndex = () => {
|
||||
switch (screenSize) {
|
||||
case "lg":
|
||||
return 15;
|
||||
case "md":
|
||||
return 12;
|
||||
case "sm":
|
||||
return 7;
|
||||
default:
|
||||
return 15;
|
||||
}
|
||||
};
|
||||
|
||||
const fetchMediaItems = async () => {
|
||||
try {
|
||||
const response = await fetch(
|
||||
"https://api.storyteller.ai/v1/media_files/list_featured?page_size=63&filter_media_classes=video"
|
||||
);
|
||||
const data = await response.json();
|
||||
if (data.success) {
|
||||
setMediaItems(data.results);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error fetching media items:", error);
|
||||
}
|
||||
};
|
||||
|
||||
const renderGridItems = () => {
|
||||
const gridItems = [];
|
||||
const customGridItemIndex = getCustomGridItemIndex();
|
||||
|
||||
for (let i = 1; i <= totalGrids; i++) {
|
||||
const isBlank = blankGrids.includes(i);
|
||||
if (screenSize === "sm") {
|
||||
if (i === 10) {
|
||||
gridItems.push(
|
||||
<div
|
||||
key="10-12"
|
||||
className={`grid-item triple-grid grid-item-custom ${
|
||||
isBlank ? "blank" : ""
|
||||
}`}
|
||||
>
|
||||
<button className="waitlist-button">
|
||||
Join the Waitlist
|
||||
<FontAwesomeIcon icon={faArrowRight} className="ms-2 fs-6" />
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
} else if (screenSize === "md") {
|
||||
if (i === 17) {
|
||||
gridItems.push(
|
||||
<div
|
||||
key="17-19"
|
||||
className={`grid-item triple-grid grid-item-custom ${
|
||||
isBlank ? "blank" : ""
|
||||
}`}
|
||||
>
|
||||
<button className="waitlist-button">
|
||||
Join the Waitlist
|
||||
<FontAwesomeIcon icon={faArrowRight} className="ms-2 fs-6" />
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
i += 2;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (i === 22) {
|
||||
gridItems.push(
|
||||
<div
|
||||
key="22-23"
|
||||
className={`grid-item double-grid grid-item-custom ${
|
||||
isBlank ? "blank" : ""
|
||||
}`}
|
||||
>
|
||||
<button className="waitlist-button">
|
||||
Join the Waitlist
|
||||
<FontAwesomeIcon icon={faArrowRight} className="ms-2 fs-6" />
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
const mediaItem = mediaItems[i - 1];
|
||||
const bucketConfig = new BucketConfig();
|
||||
const gifUrl = mediaItem
|
||||
? bucketConfig.getCdnUrl(
|
||||
mediaItem.public_bucket_path + "-thumb.gif",
|
||||
360,
|
||||
20
|
||||
)
|
||||
: "";
|
||||
|
||||
gridItems.push(
|
||||
<div key={i} className={`grid-item ${isBlank ? "blank" : ""}`}>
|
||||
{!isBlank ? (
|
||||
<img src="/images/dummy-image.jpg" className="w-100 h-100" />
|
||||
<div
|
||||
key={i}
|
||||
className={`grid-item ${isBlank ? "blank" : ""} ${
|
||||
i === customGridItemIndex ? "grid-item-custom" : ""
|
||||
}`.trim()}
|
||||
>
|
||||
{isBlank ? (
|
||||
i === customGridItemIndex ? (
|
||||
<img
|
||||
className="logo"
|
||||
src="/fakeyou/Storyteller-Logo-1.png"
|
||||
alt="Storyteller Logo"
|
||||
/>
|
||||
) : null
|
||||
) : mediaItem ? (
|
||||
<img
|
||||
onClick={() =>
|
||||
window.open(`https://storyteller.ai/media/${mediaItem.token}`)
|
||||
}
|
||||
src={gifUrl}
|
||||
className="w-100 h-100 object-fit-cover"
|
||||
alt={`Video by ${mediaItem.maybe_creator.username}`}
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
@@ -21,15 +171,7 @@ const PrelaunchLanding: React.FC = () => {
|
||||
return gridItems;
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="grid-container">
|
||||
{renderGridItems()}
|
||||
|
||||
<img className="logo" src="/fakeyou/Storyteller-Logo-1.png" />
|
||||
|
||||
<button className="waitlist-button">Join the Waitlist</button>
|
||||
</div>
|
||||
);
|
||||
return <div className="grid-container">{renderGridItems()}</div>;
|
||||
};
|
||||
|
||||
export default PrelaunchLanding;
|
||||
Reference in new issue
Block a user