add favorite to congress
This commit is contained in:
parent
067129630d
commit
2b5b4e3bdd
@ -3,25 +3,26 @@
|
|||||||
import democraticBackground from "$lib/images/bg-democratic.png";
|
import democraticBackground from "$lib/images/bg-democratic.png";
|
||||||
import otherBackground from "$lib/images/bg-other.png";
|
import otherBackground from "$lib/images/bg-other.png";
|
||||||
|
|
||||||
import { screenWidth, numberOfUnreadNotification } from "$lib/store";
|
import { numberOfUnreadNotification } from "$lib/store";
|
||||||
import { abbreviateNumber } from "$lib/utils";
|
import { abbreviateNumber } from "$lib/utils";
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
|
import { page } from "$app/stores";
|
||||||
|
|
||||||
import { compareTwoStrings } from "string-similarity";
|
import { compareTwoStrings } from "string-similarity";
|
||||||
// import * as XLSX from 'xlsx';
|
// import * as XLSX from 'xlsx';
|
||||||
|
|
||||||
export let data;
|
export let data;
|
||||||
|
|
||||||
let cloudFrontUrl = import.meta.env.VITE_IMAGE_URL;
|
let cloudFrontUrl = import.meta.env.VITE_IMAGE_URL;
|
||||||
|
let pagePathName = $page?.url?.pathname;
|
||||||
|
|
||||||
let rawData = data?.getAllPolitician;
|
let rawData = data?.getAllPolitician;
|
||||||
let displayList = [];
|
let displayList = [];
|
||||||
let filterQuery = "";
|
let filterQuery = "";
|
||||||
|
|
||||||
let isLoaded = false;
|
let isLoaded = false;
|
||||||
|
let animationClass = "";
|
||||||
let filterList = [];
|
let animationId = "";
|
||||||
|
let favoriteList = [];
|
||||||
let changeRuleFilter = false;
|
|
||||||
|
|
||||||
async function handleScroll() {
|
async function handleScroll() {
|
||||||
const scrollThreshold = document.body.offsetHeight * 0.8; // 80% of the website height
|
const scrollThreshold = document.body.offsetHeight * 0.8; // 80% of the website height
|
||||||
@ -34,6 +35,28 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
|
try {
|
||||||
|
const savedList = localStorage?.getItem(pagePathName);
|
||||||
|
|
||||||
|
if (savedList) {
|
||||||
|
favoriteList = JSON?.parse(savedList);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
rawData?.sort((a, b) => {
|
||||||
|
// Check if each id is in the favoriteList
|
||||||
|
const aIsFavorite = favoriteList?.includes(a?.id);
|
||||||
|
const bIsFavorite = favoriteList?.includes(b?.id);
|
||||||
|
|
||||||
|
// If both are favorites or both are not, keep their order
|
||||||
|
if (aIsFavorite === bIsFavorite) return 0;
|
||||||
|
|
||||||
|
// If a is favorite and b is not, a comes first; otherwise, b comes first
|
||||||
|
return aIsFavorite ? -1 : 1;
|
||||||
|
});
|
||||||
|
|
||||||
displayList = rawData?.slice(0, 20) ?? [];
|
displayList = rawData?.slice(0, 20) ?? [];
|
||||||
isLoaded = true;
|
isLoaded = true;
|
||||||
|
|
||||||
@ -47,59 +70,6 @@
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
async function handleFilter(e, newFilter) {
|
|
||||||
//e.preventDefault();
|
|
||||||
|
|
||||||
changeRuleFilter = true;
|
|
||||||
const filterSet = new Set(filterList);
|
|
||||||
|
|
||||||
// Check if the new filter already exists in the list
|
|
||||||
if (filterSet?.has(newFilter)) {
|
|
||||||
// If it exists, remove it from the list
|
|
||||||
filterSet?.delete(newFilter);
|
|
||||||
} else {
|
|
||||||
// If it doesn't exist, add it to the list
|
|
||||||
filterSet?.add(newFilter);
|
|
||||||
}
|
|
||||||
filterList = Array?.from(filterSet);
|
|
||||||
//console.log(filterList)
|
|
||||||
changeRuleFilter = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function filterData(data) {
|
|
||||||
const newData = data?.filter((item) => {
|
|
||||||
//Democratic Party nested conditions
|
|
||||||
if (
|
|
||||||
filterList?.includes("Democratic") &&
|
|
||||||
item?.party &&
|
|
||||||
item?.party?.toLowerCase() === "democratic"
|
|
||||||
) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
//Republican Party nested conditions
|
|
||||||
if (
|
|
||||||
filterList?.includes("Republican") &&
|
|
||||||
item?.party &&
|
|
||||||
item?.party?.toLowerCase() === "republican"
|
|
||||||
) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Other Party nested conditions
|
|
||||||
if (
|
|
||||||
filterList?.includes("Other") &&
|
|
||||||
item?.party &&
|
|
||||||
item?.party?.toLowerCase() === "other"
|
|
||||||
) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return newData;
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleInput(event) {
|
function handleInput(event) {
|
||||||
filterQuery = event.target.value?.toLowerCase();
|
filterQuery = event.target.value?.toLowerCase();
|
||||||
let newData = [];
|
let newData = [];
|
||||||
@ -134,14 +104,41 @@
|
|||||||
}, 500);
|
}, 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
$: {
|
function saveList() {
|
||||||
if (filterList && changeRuleFilter === true) {
|
try {
|
||||||
displayList = filterList?.length !== 0 ? filterData(rawData) : rawData;
|
// Save the version along with the rules
|
||||||
displayList = [...displayList];
|
localStorage?.setItem(pagePathName, JSON?.stringify(favoriteList));
|
||||||
changeRuleFilter = false;
|
} catch (e) {
|
||||||
//console.log(slicedRawData?.length)
|
console.log("Failed saving indicator rules: ", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function addToFavorite(event, itemId) {
|
||||||
|
event?.preventDefault();
|
||||||
|
if (favoriteList.includes(itemId)) {
|
||||||
|
// Remove ticker from the watchlist.
|
||||||
|
favoriteList = favoriteList?.filter((item) => item !== itemId);
|
||||||
|
} else {
|
||||||
|
// Add ticker to the watchlist.
|
||||||
|
animationId = itemId;
|
||||||
|
animationClass = "heartbeat";
|
||||||
|
const removeAnimation = () => {
|
||||||
|
animationId = "";
|
||||||
|
animationClass = "";
|
||||||
|
};
|
||||||
|
favoriteList = [...favoriteList, itemId];
|
||||||
|
const heartbeatElement = document.getElementById(itemId);
|
||||||
|
if (heartbeatElement) {
|
||||||
|
// Only add listener if it's not already present
|
||||||
|
if (!heartbeatElement.classList.contains("animation-added")) {
|
||||||
|
heartbeatElement.addEventListener("animationend", removeAnimation);
|
||||||
|
heartbeatElement.classList.add("animation-added"); // Prevent re-adding listener
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
saveList();
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- HEADER FOR BETTER SEO -->
|
<!-- HEADER FOR BETTER SEO -->
|
||||||
@ -233,7 +230,7 @@
|
|||||||
>
|
>
|
||||||
</label>
|
</label>
|
||||||
</li>
|
</li>
|
||||||
|
<!--
|
||||||
<li
|
<li
|
||||||
class="pl-3 py-1.5 flex-auto text-center bg-[#2E3238] rounded-[3px]"
|
class="pl-3 py-1.5 flex-auto text-center bg-[#2E3238] rounded-[3px]"
|
||||||
>
|
>
|
||||||
@ -257,6 +254,7 @@
|
|||||||
>
|
>
|
||||||
</label>
|
</label>
|
||||||
</li>
|
</li>
|
||||||
|
-->
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -276,6 +274,26 @@
|
|||||||
: 'sm:hover:shadow-[#636465]'} border-gray-600 shadow-md rounded-md h-auto pb-4 pt-4 mb-7"
|
: 'sm:hover:shadow-[#636465]'} border-gray-600 shadow-md rounded-md h-auto pb-4 pt-4 mb-7"
|
||||||
>
|
>
|
||||||
<div class="flex flex-col relative">
|
<div class="flex flex-col relative">
|
||||||
|
<div
|
||||||
|
id={item?.id}
|
||||||
|
on:click|stopPropagation={(event) =>
|
||||||
|
addToFavorite(event, item?.id)}
|
||||||
|
class=" {favoriteList?.includes(item?.id)
|
||||||
|
? 'text-[#FBCE3C]'
|
||||||
|
: 'text-white'} absolute top-0 right-5 z-20"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
class="{item?.id === animationId
|
||||||
|
? animationClass
|
||||||
|
: ''} w-[22px] h-[22px] inline-block cursor-pointer flex-shrink-0"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
><path
|
||||||
|
fill="currentColor"
|
||||||
|
d="M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327l4.898.696c.441.062.612.636.282.95l-3.522 3.356l.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z"
|
||||||
|
/></svg
|
||||||
|
>
|
||||||
|
</div>
|
||||||
{#if item?.party === "Republican"}
|
{#if item?.party === "Republican"}
|
||||||
<img
|
<img
|
||||||
class="absolute -mt-4 w-full m-auto rounded-md"
|
class="absolute -mt-4 w-full m-auto rounded-md"
|
||||||
@ -382,249 +400,6 @@
|
|||||||
</body>
|
</body>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{#if $screenWidth >= 640}
|
|
||||||
<!--Start View All List-->
|
|
||||||
<input type="checkbox" id="filterList" class="modal-toggle" />
|
|
||||||
|
|
||||||
<dialog id="filterList" class="modal modal-bottom sm:modal-middle">
|
|
||||||
<label
|
|
||||||
id="filterList"
|
|
||||||
for="filterList"
|
|
||||||
class="cursor-pointer modal-backdrop bg-[#000] bg-opacity-[0.5]"
|
|
||||||
></label>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="modal-box w-full bg-[#09090B] sm:border sm:border-gray-600 max-h-[600px] overflow-y-scroll"
|
|
||||||
>
|
|
||||||
<label
|
|
||||||
for="filterList"
|
|
||||||
class="cursor-pointer absolute right-5 top-2 bg-[#09090B] text-[1.8rem] text-white"
|
|
||||||
>
|
|
||||||
✕
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<div class="text-white mt-5 pb-5">
|
|
||||||
<div class="flex flex-col items-center justify-start">
|
|
||||||
<!--Start Political Party-->
|
|
||||||
<div class="grid grid-cols-2 mt-4 w-full ml-auto mt-4">
|
|
||||||
<div class="mb-4 mr-auto">
|
|
||||||
<h2 class="text-xl sm:text-2xl text-white font-bold mb-3">
|
|
||||||
Political Party
|
|
||||||
</h2>
|
|
||||||
<ul class="space-y-1">
|
|
||||||
<li class="mb-2 cursor-pointer">
|
|
||||||
<label
|
|
||||||
on:click|stopPropagation={(event) =>
|
|
||||||
handleFilter(event, "Democratic")}
|
|
||||||
class="cursor-pointer flex w-full items-center space-x-2 py-2 md:w-1/2 lg:w-1/3 lg:space-x-1.5 lg:py-[5px]"
|
|
||||||
>
|
|
||||||
<input
|
|
||||||
checked={filterList?.includes("Democratic")}
|
|
||||||
type="checkbox"
|
|
||||||
class="cursor-pointer bg-[#2E3238] h-[18px] w-[18px] rounded-sm ring-offset-0 dark:bg-dark-600 lg:h-4 lg:w-4"
|
|
||||||
/>
|
|
||||||
<label class="text-white text-md cursor-pointer"
|
|
||||||
>Democratic</label
|
|
||||||
>
|
|
||||||
</label>
|
|
||||||
</li>
|
|
||||||
<li class="mb-2 cursor-pointer">
|
|
||||||
<label
|
|
||||||
on:click|stopPropagation={(event) =>
|
|
||||||
handleFilter(event, "Republican")}
|
|
||||||
class="cursor-pointer flex w-full items-center space-x-2 py-2 md:w-1/2 lg:w-1/3 lg:space-x-1.5 lg:py-[5px]"
|
|
||||||
>
|
|
||||||
<input
|
|
||||||
checked={filterList?.includes("Republican")}
|
|
||||||
type="checkbox"
|
|
||||||
class="cursor-pointer bg-[#2E3238] h-[18px] w-[18px] rounded-sm ring-offset-0 dark:bg-dark-600 lg:h-4 lg:w-4"
|
|
||||||
/>
|
|
||||||
<label class="text-white text-md cursor-pointer"
|
|
||||||
>Republican</label
|
|
||||||
>
|
|
||||||
</label>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<!-- Column 2 -->
|
|
||||||
<div class="mt-11">
|
|
||||||
<ul class="space-y-1">
|
|
||||||
<li class="mb-2 cursor-pointer">
|
|
||||||
<label
|
|
||||||
on:click|stopPropagation={(event) =>
|
|
||||||
handleFilter(event, "Other")}
|
|
||||||
class="cursor-pointer flex w-full items-center space-x-2 py-2 md:w-1/2 lg:w-1/3 lg:space-x-1.5 lg:py-[5px]"
|
|
||||||
>
|
|
||||||
<input
|
|
||||||
checked={filterList?.includes("Other")}
|
|
||||||
type="checkbox"
|
|
||||||
class="cursor-pointer bg-[#2E3238] h-[18px] w-[18px] rounded-sm ring-offset-0 dark:bg-dark-600 lg:h-4 lg:w-4"
|
|
||||||
/>
|
|
||||||
<label class="text-white text-md cursor-pointer"
|
|
||||||
>Other</label
|
|
||||||
>
|
|
||||||
</label>
|
|
||||||
</li>
|
|
||||||
<!-- ...other list items -->
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!--End Political Party-->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</dialog>
|
|
||||||
<!--End View All List-->
|
|
||||||
{:else}
|
|
||||||
<div class="drawer drawer-end z-40 overflow-hidden w-screen">
|
|
||||||
<input id="filterList" type="checkbox" class="drawer-toggle" />
|
|
||||||
<div class="drawer-side overflow-y-scroll overflow-hidden">
|
|
||||||
<div
|
|
||||||
class="bg-[#000] min-h-screen w-screen pb-20 overflow-y-scroll overflow-hidden"
|
|
||||||
>
|
|
||||||
<label for="filterList" class="absolute left-6 top-6">
|
|
||||||
<svg
|
|
||||||
class="w-6 h-6 inline-block mb-0.5"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
><path
|
|
||||||
fill="#fff"
|
|
||||||
d="M9.125 21.1L.7 12.7q-.15-.15-.213-.325T.425 12q0-.2.063-.375T.7 11.3l8.425-8.425q.35-.35.875-.35t.9.375q.375.375.375.875t-.375.875L3.55 12l7.35 7.35q.35.35.35.863t-.375.887q-.375.375-.875.375t-.875-.375Z"
|
|
||||||
/></svg
|
|
||||||
>
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<div class="w-screen overflow-y-scroll">
|
|
||||||
<div class="space-y-3 sm:pt-5">
|
|
||||||
<div class="bg-[#000] h-auto w-screen">
|
|
||||||
<!--Start Header-->
|
|
||||||
<div
|
|
||||||
class="bg-[#000] w-full p-1 flex flex-col items-center pb-10 h-auto"
|
|
||||||
>
|
|
||||||
<h2
|
|
||||||
class="text-center m-auto text-[1.1rem] font-medium text-white mt-5"
|
|
||||||
>
|
|
||||||
Filter List
|
|
||||||
</h2>
|
|
||||||
</div>
|
|
||||||
<!--End Header-->
|
|
||||||
|
|
||||||
<div class="flex flex-col items-center justify-center">
|
|
||||||
<!--Start Political Party-->
|
|
||||||
<div class="grid grid-cols-2 mt-4 w-11/12 ml-auto mt-4">
|
|
||||||
<div class="mb-4 mr-auto">
|
|
||||||
<h2 class="text-xl sm:text-2xl text-white font-bold mb-3">
|
|
||||||
Political Party
|
|
||||||
</h2>
|
|
||||||
<ul class="space-y-1">
|
|
||||||
<li class="mb-2 cursor-pointer">
|
|
||||||
<label
|
|
||||||
on:click|stopPropagation={(event) =>
|
|
||||||
handleFilter(event, "Democratic")}
|
|
||||||
class="flex w-full items-center space-x-2 py-2 md:w-1/2 lg:w-1/3 lg:space-x-1.5 lg:py-[5px]"
|
|
||||||
>
|
|
||||||
<input
|
|
||||||
checked={filterList?.includes("Democratic")}
|
|
||||||
type="checkbox"
|
|
||||||
class="bg-[#2E3238] h-[18px] w-[18px] rounded-sm ring-offset-0 dark:bg-dark-600 lg:h-4 lg:w-4"
|
|
||||||
/>
|
|
||||||
<label class="text-white text-md">Democratic</label>
|
|
||||||
</label>
|
|
||||||
</li>
|
|
||||||
<li class="mb-2 cursor-pointer">
|
|
||||||
<label
|
|
||||||
on:click|stopPropagation={(event) =>
|
|
||||||
handleFilter(event, "Republican")}
|
|
||||||
class="flex w-full items-center space-x-2 py-2 md:w-1/2 lg:w-1/3 lg:space-x-1.5 lg:py-[5px]"
|
|
||||||
>
|
|
||||||
<input
|
|
||||||
checked={filterList?.includes("Republican")}
|
|
||||||
type="checkbox"
|
|
||||||
class="bg-[#2E3238] h-[18px] w-[18px] rounded-sm ring-offset-0 dark:bg-dark-600 lg:h-4 lg:w-4"
|
|
||||||
/>
|
|
||||||
<label class="text-white text-md">Republican</label>
|
|
||||||
</label>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<!-- Column 2 -->
|
|
||||||
<div class="mt-10">
|
|
||||||
<ul class="space-y-1">
|
|
||||||
<li class="mb-2 cursor-pointer">
|
|
||||||
<label
|
|
||||||
on:click|stopPropagation={(event) =>
|
|
||||||
handleFilter(event, "Other")}
|
|
||||||
class="flex w-full items-center space-x-2 py-2 md:w-1/2 lg:w-1/3 lg:space-x-1.5 lg:py-[5px]"
|
|
||||||
>
|
|
||||||
<input
|
|
||||||
checked={filterList?.includes("Other")}
|
|
||||||
type="checkbox"
|
|
||||||
class="bg-[#2E3238] h-[18px] w-[18px] rounded-sm ring-offset-0 dark:bg-dark-600 lg:h-4 lg:w-4"
|
|
||||||
/>
|
|
||||||
<span class="text-white text-md">Other</span>
|
|
||||||
</label>
|
|
||||||
</li>
|
|
||||||
<!-- ...other list items -->
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!--End Political Party-->
|
|
||||||
|
|
||||||
<!--Start Transaction Type-->
|
|
||||||
<div class="grid grid-cols-2 w-11/12 ml-auto mt-4">
|
|
||||||
<div class="mb-4 mr-auto">
|
|
||||||
<h2 class="text-xl sm:text-2xl text-white font-bold mb-3">
|
|
||||||
Transaction Type
|
|
||||||
</h2>
|
|
||||||
<ul class="space-y-1">
|
|
||||||
<li class="mb-2 cursor-pointer">
|
|
||||||
<label
|
|
||||||
on:click|stopPropagation={(event) =>
|
|
||||||
handleFilter(event, "Bought")}
|
|
||||||
class="flex w-full items-center space-x-2 py-2 md:w-1/2 lg:w-1/3 lg:space-x-1.5 lg:py-[5px]"
|
|
||||||
>
|
|
||||||
<input
|
|
||||||
checked={filterList?.includes("Bought")}
|
|
||||||
type="checkbox"
|
|
||||||
class="bg-[#2E3238] h-[18px] w-[18px] rounded-sm ring-offset-0 dark:bg-dark-600 lg:h-4 lg:w-4"
|
|
||||||
/>
|
|
||||||
<label class="text-white text-md">Bought</label>
|
|
||||||
</label>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<!-- Column 2 -->
|
|
||||||
<div class="mt-10">
|
|
||||||
<ul class="space-y-1">
|
|
||||||
<li class="mb-2 cursor-pointer">
|
|
||||||
<label
|
|
||||||
on:click|stopPropagation={(event) =>
|
|
||||||
handleFilter(event, "Sold")}
|
|
||||||
class="flex w-full items-center space-x-2 py-2 md:w-1/2 lg:w-1/3 lg:space-x-1.5 lg:py-[5px]"
|
|
||||||
>
|
|
||||||
<input
|
|
||||||
checked={filterList?.includes("Sold")}
|
|
||||||
type="checkbox"
|
|
||||||
class="bg-[#2E3238] h-[18px] w-[18px] rounded-sm ring-offset-0 dark:bg-dark-600 lg:h-4 lg:w-4"
|
|
||||||
/>
|
|
||||||
<label class="text-white text-md">Sold</label>
|
|
||||||
</label>
|
|
||||||
</li>
|
|
||||||
<!-- ...other list items -->
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!--End Transaction Type-->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.republican-striped {
|
.republican-striped {
|
||||||
background-image: repeating-linear-gradient(
|
background-image: repeating-linear-gradient(
|
||||||
@ -655,4 +430,27 @@
|
|||||||
#c0c3c5 20px
|
#c0c3c5 20px
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.heartbeat {
|
||||||
|
animation: heartbeat-animation 0.3s;
|
||||||
|
animation-timing-function: ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes heartbeat-animation {
|
||||||
|
0% {
|
||||||
|
transform: rotate(0deg) scale(0.95);
|
||||||
|
}
|
||||||
|
25% {
|
||||||
|
transform: rotate(10deg) scale(1.05);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: rotate(0deg) scale(1.2);
|
||||||
|
}
|
||||||
|
75% {
|
||||||
|
transform: rotate(-10deg) scale(1.05);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: rotate(0deg) scale(0.95);
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -135,7 +135,7 @@
|
|||||||
class="w-full m-auto flex flex-col sm:flex-row justify-center items-center gap-x-4 gap-y-2"
|
class="w-full m-auto flex flex-col sm:flex-row justify-center items-center gap-x-4 gap-y-2"
|
||||||
>
|
>
|
||||||
<p class="text-[1rem] text-black">
|
<p class="text-[1rem] text-black">
|
||||||
<strong class="font-semibold text-lg text-[1rem] text-black"
|
<strong class="font-semibold text-[1rem] sm:text-lg text-black"
|
||||||
>Black Friday Deal</strong
|
>Black Friday Deal</strong
|
||||||
><svg
|
><svg
|
||||||
viewBox="0 0 2 2"
|
viewBox="0 0 2 2"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user