Display event inside a grid for a resource? - css

I am trying to make a scheduler with resources. The biggest challenge for me so far is to create the events as one piece (blue in the sample). Can please someone share what would be the best approach for this task?
Second question: Also I would like to scale this later, by changing the slot step (e.g. in the sample it is a step "by 1" so slots are 1,2,3,4,5.
But later, if I want to change the step e.g. "by 5" 1,5,10...
then let's say we have an even from [7,12] - it should then show from 5-15 etc.
new Vue({
el: "#vue",
data() {
return {
slot: null,
row: null,
events: [
{ row: 1, slots: [ 3, 4 ] },
{ row: 4, slots: [ 3, 9 ] },
],
}
},
methods: {
onSelectSlot (row, slot) {
this.row = row
this.slot = slot
},
}
});
.selected-slot {
#apply bg-purple-600;
}
.selected-row {
#apply bg-green-600;
}
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<link href="https://unpkg.com/tailwindcss#^1.0/dist/tailwind.min.css" rel="stylesheet">
<div id="vue" class="p-5 bg-red-800 h-screen">
<div class="flex flex-row w-full h-full overflow-x-scroll">
<div v-for="x in 10" :key="x" class="bg-white w-60">
<div class="bg-blue-400 min-w-full flex flex-col w-full sticky top-0">
<div class="bg-green-400 flex items-center justify-center min-w-full h-10 w-full sticky top-0 shadow z-20 border-2" :class="(row === x) ? 'selected-row' : ''">
Row {{ x }}
</div>
<div v-for="y in 50" :key="y" class="w-60 h-10 border bg-purple-400 cursor-pointer flex items-center px-2 hover:bg-purple-500" :class="(row === x && y === slot) ? 'selected-slot' : ''" #click="onSelectSlot(x, y)">
Slot {{ x + ',' + y }}
<!-- events -->
<div v-for="(event,index) in events" :key="index">
<div v-if="event.row === x && (event.slots[0] <= y && event.slots[1] >= y) " class="bg-blue-500">
Event
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Can please someone help me to display the blue events in this example as one piece?

Related

React-Slick - transform: translate3d - Not working on smaller resolutions

I am using next.js and fetching data via API to slides. React-slick works great until the first break point on lower resolution (890px in this example).
.slick-track class has a property that is causing this problem.
.slick-track {transform: translate3d((wrong calc here)px, 0px, 0px)}
So instead 0px on first value inside translate 3d I'm getting value that is width of element where the list of slides should be shown. And List is moved to right so it cant bee seen.
After click on next button, list is coming to its normal place, but skipping first element in list...
Screenshot:
I have tried to overwrite this property inside module.css via :global and inside base CSS file, but it is still applied. I i put !important at end of my property it will be applied but I wont be able to scroll/navigate through elements of slide (first element will be stuck to left).
I also have tried older versions of react-slick 26.0; 26.1; 27.0; 28.0... But problem is still here.
Does anyone has some idea for solution?
Here is my component:
const Accessories = () => {
const { query } = useRegions();
const { error, data } = useAccessoriesSubcategoriesQuery({
variables: { ...query },
});
if (error) {
console.error("Accessories section component error", error.message);
}
const subcategoryItems = data?.categories.edges[0].node.children.edges || [];
// Slick slider settings
const settings = {
dots: false,
infinite: false,
speed: 500,
slidesToShow: 4,
slidesToScroll: 1,
nextArrow: <AccessoriesNextBtn currentSlide={0} slideCount={0} />,
prevArrow: <AccessoriesPrevBtn currentSlide={0} slideCount={0} />,
responsive: [
{
breakpoint: 890,
settings: {
slidesToShow: 3,
},
},
{
breakpoint: 620,
settings: {
slidesToShow: 2,
},
},
{
breakpoint: 420,
settings: {
slidesToShow: 1,
},
},
],
};
return (
<div className={"flex items-center justify-center w-full h-full bg-white"}>
<Container className="flex-col relative overflow-hidden">
<div className="flex flex-col lg:flex-row w-full mb-[50px] gap-[30px] lg:gap-[20px] justify-between">
<H2Headline className="text-[26px] text-left ">
Pool equipment & water treatment
</H2Headline>
<Button
className={`${styles.accessoriesSeeAllBtn} mb-[50px] mr-[0px] ml-auto xs:mb-0 xs:ml-0 xs:mr-auto max-w-[112px] h-[45px] box-border text-solidGray font-semibold text-[16px] leading-[157%] bg-white border border-solidGray hover:bg-solidGray hover:text-white`}
>
{/* <LinkBuilder linkItem={data?.categories.edges[0].node}>See all</LinkBuilder> */}
See All
</Button>
</div>
<div className={`${styles.accessoriesSliderWrapper} md:min-w-[500px] w-full`}>
<style jsx global>{`
.slick-track {
display: block;
transform: translate3d(0px, 0px, 0px);
}
`}</style>
<Slider {...settings}>
{subcategoryItems.map((item) => (
<div
key={item?.node.id}
className="flex flex-col max-w-[366px] md:max-w-[263px] transform hover:-translate-y-3 duration-500 ease-in-out "
>
{item.node.backgroundImage ? (
<div className="flex justify-center items-center content-center h-[280px] bg-lightGray rounded-[12px] overflow-visible z-50">
<Image
src={item.node.backgroundImage?.url}
width={218}
height={218}
alt="Category image"
className="object-cover object-center w-auto h-auto"
placeholder="blur"
blurDataURL={item.node.backgroundImage?.url}
/>
</div>
) : null}
<h3 className="text-solidGray text-[16px] leading-[160%] font-medium mt-[12px] mb-[3px]">
{item.node.name}
</h3>
<ParagraphText className="text-[14px] text-gray opacity-100 mt-[3px] mb-[12px]">
{item.node.description}
</ParagraphText>
<Button className="mx-auto text-[14px] border border-lightGray bg-white w-full hover:bg-solidGray hover:border-solidGray hover:text-white">
<LinkBuilder linkItem={item}>See all</LinkBuilder>
</Button>
</div>
))}
</Slider>
</div>
</Container>
</div>
);
};

NextJs: Multiple children were passed to <Link> with the same `href` when I map

How do I easiest map through an array of menu items using the NextJs < Link > component?
The code I have is:
{navigation.map((item) => (
<Link
key={item.name}
href={item.href}
className={classNames(
router.pathname == item.href
? 'bg-indigo-800 text-white'
: 'text-indigo-100 hover:bg-indigo-600',
'group flex items-center rounded-md px-2 py-2 text-base font-medium'
)}
>
<item.icon
className="mr-3 h-6 w-6 flex-shrink-0 text-indigo-300"
aria-hidden="true"
/>
{item.name}
</Link>
))}
Which works using < a > tags instead of < Link >. The error message I get says:
"Error: Multiple children were passed to with href of /admin/home but only one child is supported https://nextjs.org/docs/messages/link-multiple-children"
Now I could hard code the menu items, but that is not what I want to do.
The items themselves look like this:
const navigation = [
{ name: 'Dashboard', href: '/admin/home', icon: HomeIcon },
{ name: 'Users', href: '/admin/users', icon: UsersIcon },
{ name: 'Products', href: '/admin/products', icon: FolderIcon },
]
Any advice on how to do this?
So your problem is as the error says you are passing multiple children to the Link component
So if we breakdown your Link component that you are trying to map we can see the problem.
<Link>
<item.icon /> //ITEM 1
{item.name} //ITEM 2
</Link>
What you should have is a parent for the children you are trying to pass.
<Link>
<div> //This is now just 1 item
<item.icon />
{item.name}
</div>
</Link>
So your final code will end up looking like this
{navigation.map((item) => (
<Link
key={item.name}
href={item.href}
className={classNames(
router.pathname == item.href
? 'bg-indigo-800 text-white'
: 'text-indigo-100 hover:bg-indigo-600',
'group flex items-center rounded-md px-2 py-2 text-base font-medium'
)}
>
<div>
<item.icon
className="mr-3 h-6 w-6 flex-shrink-0 text-indigo-300"
aria-hidden="true"
/>
{item.name}
</div>
</Link>
))}

How to optimize drag animation (useState + transform: translate)

i have a Card component, which is draggable on mobile devices. on touch start it saves the initial point, on touch move it updates the current point state and on touch end it restores points and makes some logic with the swipe direction. it works fine when is testing on desktop but on mobile it is very sharp. how can i optimize drag animation so it works smooth?
i use "dragging" key to smooth relocate card on initial position if the distance is small
const Card = ({screens, title, overview, release_date, onSwipe}: props) => {
const [initialPoint, setInitialPoint] = useState({x: 0, y: 0})
const [currentPoint, setCurrentPoint] = useState({x: 0, y: 0})
const [dragging, setDragging] = useState(false)
const [currentStep, setCurrentStep] = useState(0)
const touchStartHandler = (e: React.TouchEvent) => {
setDragging(true)
setInitialPoint({
x: e.touches[0].pageX,
y: e.touches[0].pageY
})
setCurrentPoint({
x: e.touches[0].clientX,
y: e.touches[0].clientY
})
}
const touchMoveHandler = (e: React.TouchEvent) => {
setCurrentPoint({
x: e.touches[0].clientX,
y: e.touches[0].clientY
})
}
const touchEndHandler = () => {
if(currentPoint.x - initialPoint.x === 0) {
if(currentPoint.x > window.screen.width / 2) {if(currentStep < screens.length - 1) setCurrentStep(x => x + 1)}
else if(currentStep > 0) setCurrentStep(x => x - 1)
}
setDragging(false)
setCurrentPoint({x: 0, y: 0})
}
useEffect(() => {
preload(screens)
}, [screens])
return (
<div
style={{
transform: `translate(${currentPoint.x - initialPoint.x}px, ${currentPoint.y - initialPoint.y}px) rotate(${(window.screenX - currentPoint.x + initialPoint.x)/45}deg)`,
transition: dragging ? '0s' : '200ms'
}}
onTouchStart={touchStartHandler}
onTouchMove={touchMoveHandler}
onTouchEnd={touchEndHandler}
className={`w-[100%] h-[100%] box-border rounded-2xl absolute overflow-hidden bg-black`}
>
<div style={{backgroundImage: `url('${screens[currentStep]}')`}} className={'w-[120%] h-[120%] box-border rounded-2xl bg-black bg-cover bg-center blur-lg absolute left-[-10%] top-[-10%] opacity-50'}/>
<Stamps currentPoint={currentPoint} initialPoint={initialPoint}/>
<div className={'bg-contain bg-center bg-no-repeat h-full absolute w-full top-0 rounded-2xl'} style={{backgroundImage: `url('${screens[currentStep]}')`}}/>
<Counter current={currentStep} total={screens.length}/>
<div
className={'bg-rose-100 absolute bottom-0 rounded-2xl w-full text-black p-4'}>
<div className={'font-bold text-3xl'}>{title}</div>
<div className={'mt-2 font-medium'}>{release_date.split('-')[0]}, комедия, триллер</div>
<div className={'leading-4 mt-2 max-h-20 overflow-hidden relative'}>
{overview}
<div className={'bg-gradient-to-b from-transparent to-rose-100 absolute w-full h-full max-h-20 top-0'}/>
</div>
<div className={'text-lg font-medium underline'}>Полностью на themoviedb.org</div>
</div>
</div>
);
};
const Stamps = ({currentPoint, initialPoint}: {currentPoint: point, initialPoint: point}) => {
return (
<>
<div style={{opacity: (currentPoint.x - initialPoint.x - 50) / window.screen.width * 6}}
className={'font-bold text-green-400 text-4xl absolute top-28 z-30 border-4 border-green-400 p-4 rounded-2xl rotate-[35deg] left-12'}>НРАВИТСЯ</div>
<div style={{opacity: (-currentPoint.x + initialPoint.x - 50) / window.screen.width * 6}}
className={'font-bold text-red-400 text-4xl absolute top-28 z-30 border-4 border-red-400 p-4 rounded-2xl -rotate-[35deg] right-12'}>НУ ТАКОЕ</div>
<div style={Math.abs(currentPoint.x - initialPoint.x) < 50 ? {opacity: (-currentPoint.y + initialPoint.y - 50) / window.screen.height * 6} : {opacity: 0}}
className={'font-bold text-blue-400 text-4xl absolute bottom-56 z-30 border-4 border-blue-400 p-4 rounded-2xl -rotate-12 right-16'}>ПОСМОТРЮ</div>
<div style={Math.abs(currentPoint.x - initialPoint.x) < 50 ? {opacity: (currentPoint.y - initialPoint.y - 50) / window.screen.height * 6} : {opacity : 0}}
className={'font-bold text-gray-400 text-4xl absolute top-28 z-30 border-4 border-gray-400 p-4 rounded-2xl rotate-12 right-8'}>ПРОПУСТИТЬ</div>
</>
);
};
const Counter = ({current, total}: props) => {
const a = new Array(total).fill(false)
return (
<div className={'flex flex-row gap-4 h-5 pt-4 px-4 z-10 absolute top-0 w-full box-border'}>
{a.map((_, i) => {
if(i === current) return <div key={`active-${i}`} className={'bg-gradient-to-br from-[#FDABDD] to-[#374A5A] rounded-full flex h-full w-full'}/>
else return <div key={`passive-${i}`} className={'bg-rose-50 rounded-full flex h-full w-full'}/>
})}
</div>
);
};
also there is no more than 2 cards displayed in one time
lol, i just tried to add to Card class "will-change-transform" and it boosted my animation to 60 fps

Adjust width Swiper React to screen

I am using Swiper React to creater a Carousel Slider from a map of an object received from an API.
Here is my code :
<div className="border-4">
<Swiper
className='width-carousel'
modules={[Navigation]}
spaceBetween={40}
slidesPerView={2.5}
pagination={{ clickable: true }}
autoplay={{ delay: 2500, disableOnInteraction: false }}
>
{props.mediaArea.mediaObjects && props.mediaArea.mediaObjects.map((slide, index) => {
return (
<SwiperSlide key={index}>
<img className="rounded-lg shadow-lg p-3 h-96" src={slide.contentUrl ?? "https://dummyimage.com/600x400/000/fff"} alt={slide.title ?? ""} />
{slide.title && <p className="font-Montserrat font-semibold mt-8">{slide.title}</p>}
{slide.description && <p className="font-Montserrat text-gray-500 text-sm">{slide.description}</p>}
</SwiperSlide>
)
})}
</Swiper>
</div >
The problem is : If I set 100% width in my class, the sidebar will be larger than the screen because I have a sidebar of 300px.
If I make calc(100% - 300px), the calculation is not taken in consideration (the size of Swiper still 100%).
I would like it to fit the width of the <section> it is into.
Any help on this ?
PS : I set the container to width : 100%.

React owl-corusel show only fitted items

I am using owl-corusel in my React Project. I have a problem, the problem is that if an owl-item doesn't fit right on the screen I don't want it to show up. Just center and show how many items appear complete.
Here is my React code :
<OwlCarousel
className="owl-theme"
dots={false}
loop={true}
margin={2}
nav={true}
items={categoryTags.length}
autoWidth={true}
center={true}
>
{categoryTags
? categoryTags.map((item) => {
return (
<div className="item" key={`tag_item_${item.id}`}>
<Link style={{ width: "100%" }} to={"/c/" + item.slug}>
<img
src={item.avatar_url}
alt={item.title}
className="full_height full_height"
/>
<div className="flex align_center cat_ico_hover full_width full_height justify_center">
<i
className="cat_ico"
style={{ backgroundImage: `url(${item.icon_url})` }}
></i>
<span>{item.label}</span>
</div>
</Link>
</div>
);
})
: null}
</OwlCarousel>

Resources