base done
2
.gitignore
vendored
@@ -23,7 +23,7 @@ tasks
|
|||||||
|
|
||||||
# Temp
|
# Temp
|
||||||
gitignore
|
gitignore
|
||||||
*_migration_source
|
#*_migration_source
|
||||||
|
|
||||||
# System Files
|
# System Files
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|||||||
@@ -2,17 +2,17 @@ import { Typewriter } from "./Typewriter";
|
|||||||
|
|
||||||
export function LeftBar() {
|
export function LeftBar() {
|
||||||
return (
|
return (
|
||||||
<nav class="w-fit max-w-[25%] min-h-screen h-full border-r-2 border-r-maroon flex flex-col text-text text-xl font-bold py-10 px-4 gap-4 text-left">
|
<nav class="w-fit max-w-[25%] min-h-screen h-full border-r-2 border-r-overlay2 flex flex-col text-text text-xl font-bold py-10 px-4 gap-4 text-left">
|
||||||
<Typewriter keepAlive={false}>
|
<Typewriter keepAlive={false} class="z-50">
|
||||||
<h3 class="text-2xl">Left Navigation</h3>
|
<h3 class="text-2xl">Left Navigation</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li class="hover:-translate-y-0.5 transition-transform duration-200 ease-in-out hover:text-green hover:font-bold hover:scale-110">
|
<li class="hover:-translate-y-0.5 transition-transform duration-200 ease-in-out hover:text-subtext0 hover:font-bold hover:scale-110">
|
||||||
<a href="#home">Home</a>
|
<a href="#home">Home</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="hover:-translate-y-0.5 transition-transform duration-200 ease-in-out hover:text-green hover:font-bold hover:scale-110">
|
<li class="hover:-translate-y-0.5 transition-transform duration-200 ease-in-out hover:text-subtext0 hover:font-bold hover:scale-110">
|
||||||
<a href="#about">About</a>
|
<a href="#about">About</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="hover:-translate-y-0.5 transition-transform duration-200 ease-in-out hover:text-green hover:font-bold hover:scale-110">
|
<li class="hover:-translate-y-0.5 transition-transform duration-200 ease-in-out hover:text-subtext0 hover:font-bold hover:scale-110">
|
||||||
<a href="#services">Services</a>
|
<a href="#services">Services</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -23,17 +23,17 @@ export function LeftBar() {
|
|||||||
|
|
||||||
export function RightBar() {
|
export function RightBar() {
|
||||||
return (
|
return (
|
||||||
<nav class="w-fit max-w-[25%] min-h-screen h-full border-l-2 border-l-maroon flex flex-col text-text text-xl font-bold py-10 px-4 gap-4 text-right">
|
<nav class="w-fit max-w-[25%] min-h-screen h-full border-l-2 border-l-overlay2 flex flex-col text-text text-xl font-bold py-10 px-4 gap-4 text-right">
|
||||||
<Typewriter keepAlive={false}>
|
<Typewriter keepAlive={false} class="z-50">
|
||||||
<h3 class="text-2xl">Right Navigation</h3>
|
<h3 class="text-2xl">Right Navigation</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li class="hover:-translate-y-0.5 transition-transform duration-200 ease-in-out hover:text-green hover:font-bold hover:scale-110">
|
<li class="hover:-translate-y-0.5 transition-transform duration-200 ease-in-out hover:text-subtext0 hover:font-bold hover:scale-110">
|
||||||
<a href="#home">Home</a>
|
<a href="#home">Home</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="hover:-translate-y-0.5 transition-transform duration-200 ease-in-out hover:text-green hover:font-bold hover:scale-110">
|
<li class="hover:-translate-y-0.5 transition-transform duration-200 ease-in-out hover:text-subtext0 hover:font-bold hover:scale-110">
|
||||||
<a href="#about">About</a>
|
<a href="#about">About</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="hover:-translate-y-0.5 transition-transform duration-200 ease-in-out hover:text-green hover:font-bold hover:scale-110">
|
<li class="hover:-translate-y-0.5 transition-transform duration-200 ease-in-out hover:text-subtext0 hover:font-bold hover:scale-110">
|
||||||
<a href="#services">Services</a>
|
<a href="#services">Services</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
169
src/components/DeletionForm.tsx
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
import { createSignal, createEffect, onCleanup, Show } from "solid-js";
|
||||||
|
import CountdownCircleTimer from "~/components/CountdownCircleTimer";
|
||||||
|
import LoadingSpinner from "~/components/LoadingSpinner";
|
||||||
|
import { getClientCookie } from "~/lib/cookies.client";
|
||||||
|
|
||||||
|
export default function DeletionForm() {
|
||||||
|
// State management
|
||||||
|
const [countDown, setCountDown] = createSignal(0);
|
||||||
|
const [emailSent, setEmailSent] = createSignal(false);
|
||||||
|
const [error, setError] = createSignal("");
|
||||||
|
const [loading, setLoading] = createSignal(false);
|
||||||
|
|
||||||
|
// Form ref
|
||||||
|
let emailRef: HTMLInputElement | undefined;
|
||||||
|
let timerInterval: number | undefined;
|
||||||
|
|
||||||
|
// Calculate remaining time from cookie
|
||||||
|
const calcRemainder = (timer: string) => {
|
||||||
|
const expires = new Date(timer);
|
||||||
|
const remaining = expires.getTime() - Date.now();
|
||||||
|
const remainingInSeconds = remaining / 1000;
|
||||||
|
|
||||||
|
if (remainingInSeconds <= 0) {
|
||||||
|
setCountDown(0);
|
||||||
|
if (timerInterval) {
|
||||||
|
clearInterval(timerInterval);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setCountDown(remainingInSeconds);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check for existing timer on mount
|
||||||
|
createEffect(() => {
|
||||||
|
const timer = getClientCookie("deletionRequestSent");
|
||||||
|
if (timer) {
|
||||||
|
timerInterval = setInterval(() => calcRemainder(timer), 1000) as unknown as number;
|
||||||
|
onCleanup(() => {
|
||||||
|
if (timerInterval) {
|
||||||
|
clearInterval(timerInterval);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Form submission handler
|
||||||
|
const sendEmailTrigger = async (e: Event) => {
|
||||||
|
e.preventDefault();
|
||||||
|
setLoading(true);
|
||||||
|
setError("");
|
||||||
|
setEmailSent(false);
|
||||||
|
|
||||||
|
if (!emailRef) {
|
||||||
|
setError("Please enter your email");
|
||||||
|
setLoading(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const email = emailRef.value;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch("/api/trpc/misc.sendDeletionRequestEmail", {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify({ email }),
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await response.json();
|
||||||
|
|
||||||
|
if (response.ok && result.result?.data?.message === "request sent") {
|
||||||
|
setEmailSent(true);
|
||||||
|
const timer = getClientCookie("deletionRequestSent");
|
||||||
|
if (timer) {
|
||||||
|
if (timerInterval) {
|
||||||
|
clearInterval(timerInterval);
|
||||||
|
}
|
||||||
|
timerInterval = setInterval(() => calcRemainder(timer), 1000) as unknown as number;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const errorMsg = result.error?.message || "Failed to send deletion request";
|
||||||
|
setError(errorMsg);
|
||||||
|
}
|
||||||
|
} catch (err: any) {
|
||||||
|
console.error("Deletion request error:", err);
|
||||||
|
setError(err.message || "An error occurred");
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Countdown timer render function
|
||||||
|
const renderTime = () => {
|
||||||
|
return (
|
||||||
|
<div class="timer">
|
||||||
|
<div class="value">{countDown().toFixed(0)}</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div class="flex min-h-screen w-full justify-center">
|
||||||
|
<div class="pt-[5vh]">
|
||||||
|
<div class="text-center text-3xl tracking-widest dark:text-white">
|
||||||
|
Deletion Form
|
||||||
|
</div>
|
||||||
|
<form onSubmit={sendEmailTrigger} class="min-w-[85vw]">
|
||||||
|
<div class="flex w-full flex-col justify-evenly pt-6 md:mt-24">
|
||||||
|
<div class="mx-auto w-full justify-evenly md:flex md:w-3/4 md:flex-row lg:w-1/2">
|
||||||
|
<div class="input-group md:mx-4">
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
required
|
||||||
|
ref={emailRef}
|
||||||
|
placeholder=" "
|
||||||
|
class="underlinedInput w-full bg-transparent"
|
||||||
|
/>
|
||||||
|
<span class="bar"></span>
|
||||||
|
<label class="underlinedInputLabel">Email</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mx-auto pt-4">
|
||||||
|
<Show
|
||||||
|
when={countDown() > 0}
|
||||||
|
fallback={
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
disabled={loading()}
|
||||||
|
class={`${
|
||||||
|
loading()
|
||||||
|
? "bg-zinc-400"
|
||||||
|
: "bg-red-400 hover:bg-red-500 active:scale-90 dark:bg-red-600 dark:hover:bg-red-700"
|
||||||
|
} flex w-36 justify-center rounded py-3 font-light text-white shadow-lg shadow-red-300 transition-all duration-300 ease-out dark:shadow-red-700`}
|
||||||
|
>
|
||||||
|
<Show when={loading()} fallback="Send Deletion Request">
|
||||||
|
<LoadingSpinner height={24} width={24} />
|
||||||
|
</Show>
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<CountdownCircleTimer
|
||||||
|
duration={60}
|
||||||
|
initialRemainingTime={countDown()}
|
||||||
|
size={48}
|
||||||
|
strokeWidth={6}
|
||||||
|
colors="#60a5fa"
|
||||||
|
>
|
||||||
|
{renderTime}
|
||||||
|
</CountdownCircleTimer>
|
||||||
|
</Show>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<div
|
||||||
|
class={`${
|
||||||
|
emailSent()
|
||||||
|
? "text-green-400"
|
||||||
|
: error() !== ""
|
||||||
|
? "text-red-400"
|
||||||
|
: "select-none opacity-0"
|
||||||
|
} mt-4 flex justify-center text-center italic transition-opacity duration-300 ease-in-out`}
|
||||||
|
>
|
||||||
|
<Show when={emailSent()} fallback={error()}>
|
||||||
|
Request Sent!
|
||||||
|
</Show>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
16
src/components/LoadingSpinner.tsx
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
export default function LoadingSpinner(props: {
|
||||||
|
height: number;
|
||||||
|
width: number;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<picture class="animate-spin-reverse flex w-full justify-center">
|
||||||
|
<source srcSet="/WhiteLogo.png" media="(prefers-color-scheme: dark)" />
|
||||||
|
<img
|
||||||
|
src="/BlackLogo.png"
|
||||||
|
alt="logo"
|
||||||
|
width={props.width}
|
||||||
|
height={props.height}
|
||||||
|
/>
|
||||||
|
</picture>
|
||||||
|
);
|
||||||
|
}
|
||||||
29
src/components/icons/BackArrow.tsx
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
const BackArrow = (props: {
|
||||||
|
height: number;
|
||||||
|
width: number;
|
||||||
|
stroke: string;
|
||||||
|
strokeWidth: number;
|
||||||
|
class?: string;
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<div class={props.class}>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
strokeWidth={props.strokeWidth}
|
||||||
|
stroke={props.stroke}
|
||||||
|
height={props.height}
|
||||||
|
width={props.width}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
d="M10.5 19.5L3 12m0 0l7.5-7.5M3 12h18"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default BackArrow;
|
||||||
25
src/components/icons/Check.tsx
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
export default function Check(props: {
|
||||||
|
strokeWidth: number;
|
||||||
|
height: number;
|
||||||
|
width: number;
|
||||||
|
class?: string;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
strokeWidth={props.strokeWidth}
|
||||||
|
stroke="currentColor"
|
||||||
|
height={props.height}
|
||||||
|
width={props.width}
|
||||||
|
class={props.class}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
d="M4.5 12.75l6 6 9-13.5"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
25
src/components/icons/CheckCircle.tsx
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
export default function CheckCircle(props: {
|
||||||
|
strokeWidth: number;
|
||||||
|
height: number;
|
||||||
|
width: number;
|
||||||
|
fillColor: string | null;
|
||||||
|
strokeColor: string | null;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill={props.fillColor || "none"}
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
strokeWidth={props.strokeWidth}
|
||||||
|
stroke={props.strokeColor || "currentColor"}
|
||||||
|
height={props.height}
|
||||||
|
width={props.width}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
23
src/components/icons/CommentIcon.tsx
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
export default function CommentIcon(props: {
|
||||||
|
strokeWidth: number;
|
||||||
|
height: number;
|
||||||
|
width: number;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
strokeWidth={props.strokeWidth}
|
||||||
|
class="fill-black dark:fill-white"
|
||||||
|
height={props.height}
|
||||||
|
width={props.width}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
d="M12 20.25c4.97 0 9-3.694 9-8.25s-4.03-8.25-9-8.25S3 7.444 3 12c0 2.104.859 4.023 2.273 5.48.432.447.74 1.04.586 1.641a4.483 4.483 0 01-.923 1.785A5.969 5.969 0 006 21c1.282 0 2.47-.402 3.445-1.087.81.22 1.668.337 2.555.337z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
23
src/components/icons/EditIcon.tsx
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
export default function EditIcon(props: {
|
||||||
|
strokeWidth: number;
|
||||||
|
height: number;
|
||||||
|
width: number;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
strokeWidth={props.strokeWidth}
|
||||||
|
height={props.height}
|
||||||
|
width={props.width}
|
||||||
|
class="stroke-zinc-800 dark:stroke-zinc-50"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L10.582 16.07a4.5 4.5 0 01-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 011.13-1.897l8.932-8.931zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0115.75 21H5.25A2.25 2.25 0 013 18.75V8.25A2.25 2.25 0 015.25 6H10"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
25
src/components/icons/InfoIcon.tsx
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
export default function InfoIcon(props: {
|
||||||
|
height: number;
|
||||||
|
width: number;
|
||||||
|
fill?: string;
|
||||||
|
stroke?: string;
|
||||||
|
strokeWidth: number;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill={props.fill ? props.fill : "none"}
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
strokeWidth={props.strokeWidth}
|
||||||
|
height={props.height}
|
||||||
|
width={props.width}
|
||||||
|
class="stroke-black dark:stroke-white"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
d="M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
24
src/components/icons/LikeIcon.tsx
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
export default function LikeIcon(props: {
|
||||||
|
strokeWidth: number;
|
||||||
|
color: string;
|
||||||
|
height: number;
|
||||||
|
width: number;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
strokeWidth={props.strokeWidth}
|
||||||
|
height={props.height}
|
||||||
|
width={props.width}
|
||||||
|
class={`${props.color} transition-colors duration-200 ease-in`}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
d="M6.633 10.5c.806 0 1.533-.446 2.031-1.08a9.041 9.041 0 012.861-2.4c.723-.384 1.35-.956 1.653-1.715a4.498 4.498 0 00.322-1.672V3a.75.75 0 01.75-.75A2.25 2.25 0 0116.5 4.5c0 1.152-.26 2.243-.723 3.218-.266.558.107 1.282.725 1.282h3.126c1.026 0 1.945.694 2.054 1.715.045.422.068.85.068 1.285a11.95 11.95 0 01-2.649 7.521c-.388.482-.987.729-1.605.729H13.48c-.483 0-.964-.078-1.423-.23l-3.114-1.04a4.501 4.501 0 00-1.423-.23H5.904M14.25 9h2.25M5.904 18.75c.083.205.173.405.27.602.197.4-.078.898-.523.898h-.908c-.889 0-1.713-.518-1.972-1.368a12 12 0 01-.521-3.507c0-1.553.295-3.036.831-4.398C3.387 10.203 4.167 9.75 5 9.75h1.053c.472 0 .745.556.5.96a8.958 8.958 0 00-1.302 4.665c0 1.194.232 2.333.654 3.375z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
39
src/components/icons/MenuBars.tsx
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
function MenuBars() {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
width="36"
|
||||||
|
height="30"
|
||||||
|
viewBox="0 0 120 100"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<g id="Mask group">
|
||||||
|
<g id="Frame 1">
|
||||||
|
<rect width="120" height="100" />
|
||||||
|
<line
|
||||||
|
id="LineA"
|
||||||
|
x1="11.5"
|
||||||
|
y1="31.5"
|
||||||
|
x2="108.5"
|
||||||
|
y2="31.5"
|
||||||
|
strokeWidth="6"
|
||||||
|
strokeLinecap="round"
|
||||||
|
class="stroke-black dark:stroke-white"
|
||||||
|
/>
|
||||||
|
<line
|
||||||
|
id="LineB"
|
||||||
|
x1="11.5"
|
||||||
|
y1="64.5"
|
||||||
|
x2="108.5"
|
||||||
|
y2="64.5"
|
||||||
|
strokeWidth="6"
|
||||||
|
strokeLinecap="round"
|
||||||
|
class="stroke-black dark:stroke-white"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MenuBars;
|
||||||
18
src/components/icons/MoonIcon.tsx
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
export const MoonIcon = (props: any) => {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width={props.size || props.width || 24}
|
||||||
|
height={props.size || props.height || 24}
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill="#E2E2E2"
|
||||||
|
d="M20.742,13.045c-0.677,0.18-1.376,0.271-2.077,0.271c-2.135,0-4.14-0.83-5.646-2.336c-2.008-2.008-2.799-4.967-2.064-7.723 c0.092-0.345-0.007-0.713-0.259-0.965C10.444,2.04,10.077,1.938,9.73,2.034C8.028,2.489,6.476,3.382,5.241,4.616 c-3.898,3.898-3.898,10.243,0,14.143c1.889,1.889,4.401,2.93,7.072,2.93c2.671,0,5.182-1.04,7.07-2.929 c1.236-1.237,2.13-2.791,2.583-4.491c0.092-0.345-0.008-0.713-0.26-0.965C21.454,13.051,21.085,12.951,20.742,13.045z M17.97,17.346c-1.511,1.511-3.52,2.343-5.656,2.343c-2.137,0-4.146-0.833-5.658-2.344c-3.118-3.119-3.118-8.195,0-11.314 c0.602-0.602,1.298-1.102,2.06-1.483c-0.222,2.885,0.814,5.772,2.89,7.848c2.068,2.069,4.927,3.12,7.848,2.891 C19.072,16.046,18.571,16.743,17.97,17.346z"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default MoonIcon;
|
||||||
13
src/components/icons/ReplyIcon.tsx
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
export default function ReplyIcon(props: { color: string; height: number; width: number }) {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 512 512"
|
||||||
|
fill={props.color}
|
||||||
|
height={props.height}
|
||||||
|
width={props.width}
|
||||||
|
>
|
||||||
|
<path d="M8.309 189.846L184.31 37.846C199.716 24.549 223.998 35.346 223.998 56.018V136.065C384.624 137.909 512 170.096 512 322.331C512 383.768 472.406 444.643 428.656 476.456C414.999 486.393 395.562 473.924 400.593 457.831C445.937 312.815 379.093 274.315 223.998 272.081V360.003C223.998 380.706 199.685 391.456 184.31 378.159L8.309 226.159C-2.754 216.596 -2.785 199.409 8.309 189.846Z" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
38
src/components/icons/SunIcon.tsx
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
export const SunIcon = (props: any) => {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width={props.size || props.width || 24}
|
||||||
|
height={props.size || props.height || 24}
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill={props.fill}
|
||||||
|
d="M6.993 12c0 2.761 2.246 5.007 5.007 5.007s5.007-2.246 5.007-5.007S14.761 6.993 12 6.993 6.993 9.239 6.993 12zM12 8.993c1.658 0 3.007 1.349 3.007 3.007S13.658 15.007 12 15.007 8.993 13.658 8.993 12 10.342 8.993 12 8.993zM10.998 19H12.998V22H10.998zM10.998 2H12.998V5H10.998zM1.998 11H4.998V13H1.998zM18.998 11H21.998V13H18.998z"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
fill={props.fill}
|
||||||
|
transform="rotate(-45.017 5.986 18.01)"
|
||||||
|
d="M4.487 17.01H7.487V19.01H4.487z"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
fill={props.fill}
|
||||||
|
transform="rotate(-45.001 18.008 5.99)"
|
||||||
|
d="M16.508 4.99H19.509V6.99H16.508z"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
fill={props.fill}
|
||||||
|
transform="rotate(-134.983 5.988 5.99)"
|
||||||
|
d="M4.487 4.99H7.487V6.99H4.487z"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
fill={props.fill}
|
||||||
|
transform="rotate(134.999 18.008 18.01)"
|
||||||
|
d="M17.008 16.51H19.008V19.511000000000003H17.008z"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SunIcon;
|
||||||
27
src/components/icons/TrashIcon.tsx
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
const TrashIcon = (props: {
|
||||||
|
height: number;
|
||||||
|
width: number;
|
||||||
|
stroke?: string;
|
||||||
|
strokeWidth: number;
|
||||||
|
class?: string;
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
strokeWidth={props.strokeWidth}
|
||||||
|
stroke={props.stroke ? props.stroke : undefined}
|
||||||
|
height={props.height}
|
||||||
|
width={props.width}
|
||||||
|
class={props.stroke ? undefined : "stroke-zinc-900 dark:stroke-white"}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default TrashIcon;
|
||||||
25
src/components/icons/UpDownArrows.tsx
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
export default function UpDownArrows(props: {
|
||||||
|
strokeWidth: number;
|
||||||
|
height: number;
|
||||||
|
width: number;
|
||||||
|
class?: string;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
strokeWidth={props.strokeWidth}
|
||||||
|
stroke="currentColor"
|
||||||
|
height={props.height}
|
||||||
|
width={props.width}
|
||||||
|
class={props.class}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
d="M3 7.5L7.5 3m0 0L12 7.5M7.5 3v13.5m13.5 0L16.5 21m0 0L12 16.5m4.5 4.5V7.5"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
23
src/components/icons/UserDefaultImage.tsx
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
export default function UserDefaultImage(props: {
|
||||||
|
strokeWidth: number;
|
||||||
|
height: number;
|
||||||
|
width: number;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
strokeWidth={props.strokeWidth}
|
||||||
|
height={props.height}
|
||||||
|
width={props.width}
|
||||||
|
class="fill-black dark:fill-white"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
d="M15.75 6a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0zM4.501 20.118a7.5 7.5 0 0114.998 0A17.933 17.933 0 0112 21.75c-2.676 0-5.216-.584-7.499-1.632z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
25
src/components/icons/XCircle.tsx
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
export default function XCircle(props: {
|
||||||
|
height: number;
|
||||||
|
width: number;
|
||||||
|
stroke: string;
|
||||||
|
strokeWidth: number;
|
||||||
|
fill?: string | null;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill={props.fill || "white"}
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
strokeWidth={props.strokeWidth}
|
||||||
|
stroke={props.stroke}
|
||||||
|
height={props.height}
|
||||||
|
width={props.width}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
d="M9.75 9.75l4.5 4.5m0-4.5l-4.5 4.5M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
28
src/components/icons/Xmark.tsx
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
function Xmark(props: {
|
||||||
|
strokeWidth: number;
|
||||||
|
color: string;
|
||||||
|
height: number;
|
||||||
|
width: number;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
strokeWidth={props.strokeWidth}
|
||||||
|
stroke={props.color}
|
||||||
|
height={props.height}
|
||||||
|
width={props.width}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
d="M6 18L18 6M6 6l12 12"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Xmark;
|
||||||
1
src/components/icons/emojis/Angry.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><defs><style>.a{fill:#e7253e;}.b{fill:#b51f36;}.c{fill:#90192d;}</style></defs><rect class="a" x="1" y="1" width="22" height="22" rx="7.656"/><path class="b" d="M23,13.938a14.69,14.69,0,0,1-12.406,6.531c-5.542,0-6.563-1-9.142-2.529A7.66,7.66,0,0,0,8.656,23h6.688A7.656,7.656,0,0,0,23,15.344Z"/><path class="c" d="M9.565,8.513A16.121,16.121,0,0,1,5.63,6.328a.52.52,0,0,0-.832.4c-.048,1.583.151,4.483,2.258,4.483A2.6,2.6,0,0,0,9.9,9.1.517.517,0,0,0,9.565,8.513Z"/><path class="c" d="M19.2,6.731a.521.521,0,0,0-.832-.4,16.121,16.121,0,0,1-3.935,2.185A.517.517,0,0,0,14.1,9.1a2.6,2.6,0,0,0,2.84,2.11C19.051,11.214,19.25,8.314,19.2,6.731Z"/><path class="c" d="M14,13.937a.318.318,0,0,1-.313-.326,2.105,2.105,0,0,0-.5-1.331A1.6,1.6,0,0,0,12,11.847a1.6,1.6,0,0,0-1.187.43,2.092,2.092,0,0,0-.5,1.335.32.32,0,0,1-.64.012,2.715,2.715,0,0,1,.679-1.792A2.211,2.211,0,0,1,12,11.207a2.211,2.211,0,0,1,1.647.625,2.721,2.721,0,0,1,.679,1.792A.321.321,0,0,1,14,13.937Z"/></svg>
|
||||||
|
After Width: | Height: | Size: 1020 B |
1
src/components/icons/emojis/Blank.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><defs><style>.a{fill:#f8de40;}.b{fill:#864e20;}.c{fill:#e7c930;}</style></defs><rect class="a" x="1" y="1" width="22" height="22" rx="7.656"/><path class="b" d="M7.055,7.313A1.747,1.747,0,1,0,8.8,9.059,1.747,1.747,0,0,0,7.055,7.313Z"/><path class="b" d="M16.958,7.313A1.747,1.747,0,1,0,18.7,9.059,1.747,1.747,0,0,0,16.958,7.313Z"/><path class="c" d="M23,13.938a14.688,14.688,0,0,1-12.406,6.531c-5.542,0-6.563-1-9.142-2.529A7.66,7.66,0,0,0,8.656,23h6.688A7.656,7.656,0,0,0,23,15.344Z"/></svg>
|
||||||
|
After Width: | Height: | Size: 551 B |
1
src/components/icons/emojis/Cry.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><defs><style>.a{fill:#f8de40;}.b{fill:#e7c930;}.c{fill:#864e20;}.d{fill:#26a9e0;}</style></defs><rect class="a" x="1" y="1" width="22" height="22" rx="7.656"/><path class="b" d="M23,13.938a14.688,14.688,0,0,1-12.406,6.531c-5.542,0-6.563-1-9.142-2.529A7.66,7.66,0,0,0,8.656,23h6.688A7.656,7.656,0,0,0,23,15.344Z"/><path class="c" d="M17.2,12.746c-1.221-1.647-3.789-2.231-5.2-2.231s-3.984.584-5.2,2.231-.188,3.4,1.128,3.293,3.546-.364,4.077-.364,2.762.258,4.077.364S18.427,14.392,17.2,12.746Z"/><path class="b" d="M14.505,17.022A12.492,12.492,0,0,0,12,16.638a12.457,12.457,0,0,0-2.5.384c-.376.076-.39.384,0,.332s2.5-.166,2.5-.166,2.119.115,2.505.166S14.88,17.1,14.505,17.022Z"/><path class="c" d="M8.907,9.844a.182.182,0,0,1-.331.1,2.016,2.016,0,0,0-.569-.567,1.731,1.731,0,0,0-1.915,0,2.016,2.016,0,0,0-.571.569.182.182,0,0,1-.331-.1,1.632,1.632,0,0,1,.346-1.023,1.927,1.927,0,0,1,3.026,0A1.64,1.64,0,0,1,8.907,9.844Z"/><path class="c" d="M18.81,9.844a.182.182,0,0,1-.331.1,2.026,2.026,0,0,0-.568-.567,1.732,1.732,0,0,0-1.916,0,2.016,2.016,0,0,0-.571.569.182.182,0,0,1-.331-.1,1.632,1.632,0,0,1,.346-1.023,1.927,1.927,0,0,1,3.026,0A1.64,1.64,0,0,1,18.81,9.844Z"/><path class="d" d="M8.576,9.946a2.016,2.016,0,0,0-.569-.567,1.731,1.731,0,0,0-1.915,0,2.016,2.016,0,0,0-.571.569.175.175,0,0,1-.214.063v11.24A1.747,1.747,0,0,0,7.054,23h0A1.748,1.748,0,0,0,8.8,21.253V10.005A.176.176,0,0,1,8.576,9.946Z"/><path class="d" d="M18.473,9.946a2.026,2.026,0,0,0-.568-.567,1.732,1.732,0,0,0-1.916,0,2.016,2.016,0,0,0-.571.569.175.175,0,0,1-.214.063v11.24A1.748,1.748,0,0,0,16.952,23h0A1.747,1.747,0,0,0,18.7,21.253V10.005A.176.176,0,0,1,18.473,9.946Z"/></svg>
|
||||||
|
After Width: | Height: | Size: 1.7 KiB |
1
src/components/icons/emojis/Excited.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><defs><style>.a{fill:#f8de40;}.b{fill:#864e20;}.c{fill:#e7c930;}.d{fill:#fff;}.e{fill:#e6e7e8;}</style></defs><rect class="a" x="1" y="1" width="22" height="22" rx="7.656"/><path class="b" d="M8.907,9.844a.182.182,0,0,1-.331.1,2.016,2.016,0,0,0-.569-.567,1.731,1.731,0,0,0-1.915,0,2.016,2.016,0,0,0-.571.569.182.182,0,0,1-.331-.1,1.632,1.632,0,0,1,.346-1.023,1.927,1.927,0,0,1,3.026,0A1.64,1.64,0,0,1,8.907,9.844Z"/><path class="b" d="M18.81,9.844a.182.182,0,0,1-.331.1,2.026,2.026,0,0,0-.568-.567,1.732,1.732,0,0,0-1.916,0,2.016,2.016,0,0,0-.571.569.182.182,0,0,1-.331-.1,1.632,1.632,0,0,1,.346-1.023,1.927,1.927,0,0,1,3.026,0A1.64,1.64,0,0,1,18.81,9.844Z"/><path class="c" d="M23,13.938a14.69,14.69,0,0,1-12.406,6.531c-5.542,0-6.563-1-9.142-2.529A7.66,7.66,0,0,0,8.656,23h6.688A7.656,7.656,0,0,0,23,15.344Z"/><path class="d" d="M7.127,12h9.746a1.937,1.937,0,0,1,1.937,1.937v0a1.938,1.938,0,0,1-1.937,1.938H7.127a1.937,1.937,0,0,1-1.937-1.937v0A1.937,1.937,0,0,1,7.127,12Z"/><ellipse class="e" cx="12" cy="13.938" rx="6.188" ry="0.25"/><ellipse class="e" cx="7.257" cy="13.938" rx="0.208" ry="1.438"/><ellipse class="e" cx="9.628" cy="13.938" rx="0.208" ry="1.438"/><ellipse class="e" cx="12" cy="13.938" rx="0.208" ry="1.438"/><ellipse class="e" cx="14.372" cy="13.938" rx="0.208" ry="1.438"/><ellipse class="e" cx="16.743" cy="13.938" rx="0.208" ry="1.438"/></svg>
|
||||||
|
After Width: | Height: | Size: 1.4 KiB |
1
src/components/icons/emojis/Flat.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><defs><style>.a{fill:#f8de40;}.b{fill:#864e20;}.c{fill:#e7c930;}</style></defs><rect class="a" x="1" y="1" width="22" height="22" rx="7.656"/><path class="b" d="M7.055,7.313A1.747,1.747,0,1,0,8.8,9.059,1.747,1.747,0,0,0,7.055,7.313Z"/><path class="b" d="M16.958,7.313A1.747,1.747,0,1,0,18.7,9.059,1.747,1.747,0,0,0,16.958,7.313Z"/><path class="c" d="M23,13.938a14.69,14.69,0,0,1-12.406,6.531c-5.542,0-6.563-1-9.142-2.529A7.66,7.66,0,0,0,8.656,23h6.688A7.656,7.656,0,0,0,23,15.344Z"/><ellipse class="b" cx="12" cy="13.375" rx="5.479" ry="0.297"/><ellipse class="c" cx="12" cy="14.646" rx="1.969" ry="0.229"/></svg>
|
||||||
|
After Width: | Height: | Size: 673 B |
1
src/components/icons/emojis/Heart.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M472.096 270.486L278.946 470.196C266.304 483.268 245.616 483.268 232.974 470.196L39.824 270.486C-16.197 212.517 -13.104 116.653 49.041 62.862C103.316 15.884 186.371 24.359 236.32 75.925L256.007 96.249L275.694 75.925C325.641 24.36 408.694 15.884 462.969 62.859C525.118 116.649 528.212 212.515 472.096 270.486Z"/></svg>
|
||||||
|
After Width: | Height: | Size: 388 B |
1
src/components/icons/emojis/HeartEye.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><defs><style>.a{fill:#f8de40;}.b{fill:#e7c930;}.c{fill:#f06880;}.d{fill:#864e20;}</style></defs><rect class="a" x="1" y="1" width="22" height="22" rx="7.656"/><path class="b" d="M23,13.938a14.69,14.69,0,0,1-12.406,6.531c-5.542,0-6.563-1-9.142-2.529A7.66,7.66,0,0,0,8.656,23h6.688A7.656,7.656,0,0,0,23,15.344Z"/><path class="c" d="M9.58,6.983A1.528,1.528,0,0,0,7.5,7.1l-.449.45L6.6,7.1a1.529,1.529,0,0,0-2.083-.113,1.472,1.472,0,0,0-.058,2.136L6.68,11.34a.518.518,0,0,0,.737,0l2.22-2.221A1.471,1.471,0,0,0,9.58,6.983Z"/><path class="c" d="M19.483,6.983A1.528,1.528,0,0,0,17.4,7.1l-.449.45L16.5,7.1a1.529,1.529,0,0,0-2.083-.113,1.471,1.471,0,0,0-.057,2.136l2.221,2.221a.517.517,0,0,0,.736,0l2.221-2.221A1.472,1.472,0,0,0,19.483,6.983Z"/><path class="d" d="M16.666,12.583H7.334a.493.493,0,0,0-.492.544c.123,1.175.875,3.842,5.158,3.842s5.035-2.667,5.158-3.842A.493.493,0,0,0,16.666,12.583Z"/><path class="c" d="M12,16.969a6.538,6.538,0,0,0,2.959-.6,1.979,1.979,0,0,0-1.209-.853c-1.344-.3-1.75.109-1.75.109s-.406-.406-1.75-.109a1.979,1.979,0,0,0-1.209.853A6.538,6.538,0,0,0,12,16.969Z"/></svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
1
src/components/icons/emojis/MoneyEye.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><defs><style>.a{fill:#f8de40;}.b{fill:#e7c930;}.c{fill:#864e20;}.d{fill:#f06880;}.e{fill:#009345;}</style></defs><rect class="a" x="1" y="1" width="22" height="22" rx="7.656"/><path class="b" d="M23,13.938a14.69,14.69,0,0,1-12.406,6.531c-5.542,0-6.563-1-9.142-2.529A7.66,7.66,0,0,0,8.656,23h6.688A7.656,7.656,0,0,0,23,15.344Z"/><path class="c" d="M16.666,12.583H7.334a.493.493,0,0,0-.492.544c.123,1.175.875,3.842,5.158,3.842s5.035-2.667,5.158-3.842A.493.493,0,0,0,16.666,12.583Z"/><path class="d" d="M12,16.969a6.538,6.538,0,0,0,2.959-.6,1.979,1.979,0,0,0-1.209-.853c-1.344-.3-1.75.109-1.75.109s-.406-.406-1.75-.109a1.979,1.979,0,0,0-1.209.853A6.538,6.538,0,0,0,12,16.969Z"/><path class="e" d="M8.82,8.767h0a1.18,1.18,0,0,0-.378-.414A1.946,1.946,0,0,0,7.906,8.1,4.37,4.37,0,0,0,7.462,8a.094.094,0,0,1-.079-.09V6.692a.1.1,0,0,1,.036-.074A.081.081,0,0,1,7.488,6.6a.882.882,0,0,1,.375.173.579.579,0,0,1,.189.385.344.344,0,0,0,.337.3H8.5a.342.342,0,0,0,.256-.116.336.336,0,0,0,.084-.262,1.536,1.536,0,0,0-.1-.407A1.22,1.22,0,0,0,8.4,6.208a1.457,1.457,0,0,0-.5-.273,2.3,2.3,0,0,0-.44-.092.09.09,0,0,1-.077-.089V5.508a.341.341,0,0,0-.682,0v.248a.094.094,0,0,1-.086.091,1.848,1.848,0,0,0-.975.381,1.251,1.251,0,0,0-.415,1.024,1.365,1.365,0,0,0,.146.624,1.185,1.185,0,0,0,.364.409,1.711,1.711,0,0,0,.506.238c.123.036.253.069.385.1a.091.091,0,0,1,.075.088V9.944a.092.092,0,0,1-.034.072.088.088,0,0,1-.073.019,1.089,1.089,0,0,1-.45-.189.575.575,0,0,1-.209-.39A.339.339,0,0,0,5.6,9.163H5.482a.342.342,0,0,0-.34.383,1.254,1.254,0,0,0,.426.853,1.934,1.934,0,0,0,1.056.385.092.092,0,0,1,.077.093v.234a.341.341,0,0,0,.682,0v-.246a.094.094,0,0,1,.088-.091,2.069,2.069,0,0,0,1.02-.358,1.208,1.208,0,0,0,.467-1.03A1.29,1.29,0,0,0,8.82,8.767Zm-.659.611a.663.663,0,0,1-.064.306.515.515,0,0,1-.175.2.941.941,0,0,1-.287.125c-.048.013-.1.023-.148.032a.084.084,0,0,1-.07-.019.1.1,0,0,1-.034-.072V8.855a.091.091,0,0,1,.034-.07.093.093,0,0,1,.059-.021l.02,0,.125.028a1.062,1.062,0,0,1,.295.116.512.512,0,0,1,.181.18A.577.577,0,0,1,8.161,9.378ZM6.7,6.686V7.878c-.067-.013-.131-.027-.192-.044a.9.9,0,0,1-.259-.115.479.479,0,0,1-.162-.178.651.651,0,0,1-.058-.3.556.556,0,0,1,.2-.49A1.026,1.026,0,0,1,6.592,6.6l.02,0a.087.087,0,0,1,.053.019A.1.1,0,0,1,6.7,6.686Z"/><path class="e" d="M18.723,8.767a1.18,1.18,0,0,0-.378-.414,1.946,1.946,0,0,0-.536-.249A4.37,4.37,0,0,0,17.365,8a.093.093,0,0,1-.078-.09V6.692a.093.093,0,0,1,.036-.074.078.078,0,0,1,.068-.017.892.892,0,0,1,.376.173.582.582,0,0,1,.188.385.345.345,0,0,0,.337.3H18.4a.342.342,0,0,0,.256-.116.335.335,0,0,0,.084-.262,1.536,1.536,0,0,0-.1-.407,1.22,1.22,0,0,0-.332-.463,1.457,1.457,0,0,0-.5-.273,2.3,2.3,0,0,0-.44-.092.089.089,0,0,1-.076-.089V5.508a.342.342,0,0,0-.683,0v.248a.094.094,0,0,1-.086.091,1.848,1.848,0,0,0-.975.381,1.253,1.253,0,0,0-.415,1.024,1.368,1.368,0,0,0,.146.624,1.185,1.185,0,0,0,.364.409,1.711,1.711,0,0,0,.506.238c.123.036.253.069.385.1a.091.091,0,0,1,.075.088V9.944a.092.092,0,0,1-.034.072.088.088,0,0,1-.073.019,1.089,1.089,0,0,1-.45-.189.579.579,0,0,1-.209-.39.338.338,0,0,0-.336-.293h-.117a.342.342,0,0,0-.34.383,1.258,1.258,0,0,0,.426.853,1.934,1.934,0,0,0,1.056.385.092.092,0,0,1,.077.093v.234a.342.342,0,0,0,.683,0v-.246a.093.093,0,0,1,.087-.091,2.066,2.066,0,0,0,1.02-.358,1.208,1.208,0,0,0,.467-1.03A1.29,1.29,0,0,0,18.723,8.767Zm-.659.611A.663.663,0,0,1,18,9.684a.515.515,0,0,1-.175.2.93.93,0,0,1-.287.125c-.048.012-.1.023-.147.032a.086.086,0,0,1-.071-.019.094.094,0,0,1-.033-.072V8.855a.091.091,0,0,1,.033-.07.093.093,0,0,1,.059-.021l.02,0,.125.028a1.05,1.05,0,0,1,.295.116A.5.5,0,0,1,18,9.09.566.566,0,0,1,18.064,9.378ZM16.6,6.686V7.878c-.067-.013-.131-.027-.192-.044a.89.89,0,0,1-.258-.115.463.463,0,0,1-.162-.178.637.637,0,0,1-.059-.3.559.559,0,0,1,.2-.49A1.026,1.026,0,0,1,16.5,6.6l.02,0a.087.087,0,0,1,.053.019A.1.1,0,0,1,16.6,6.686Z"/></svg>
|
||||||
|
After Width: | Height: | Size: 3.8 KiB |
1
src/components/icons/emojis/Shifty.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><defs><style>.a{fill:#f8de40;}.b{fill:#e7c930;}.c{fill:#864e20;}</style></defs><rect class="a" x="1" y="1" width="22" height="22" rx="7.656"/><path class="b" d="M23,13.938a14.69,14.69,0,0,1-12.406,6.531c-5.542,0-6.563-1-9.142-2.529A7.66,7.66,0,0,0,8.656,23h6.688A7.656,7.656,0,0,0,23,15.344Z"/><path class="c" d="M18.29,9.084h-4.1a.586.586,0,0,1,0-1.171h4.1a.586.586,0,0,1,0,1.171Z"/><path class="c" d="M9.806,9.084H5.71a.586.586,0,0,1,0-1.171h4.1a.586.586,0,0,1,0,1.171Z"/><path class="c" d="M8.672,10.205A1.706,1.706,0,0,0,10.379,8.5H6.966A1.706,1.706,0,0,0,8.672,10.205Z"/><path class="c" d="M17.156,10.205A1.706,1.706,0,0,0,18.863,8.5H15.45A1.706,1.706,0,0,0,17.156,10.205Z"/><ellipse class="c" cx="12" cy="13.375" rx="5.479" ry="0.297"/><ellipse class="b" cx="12" cy="14.646" rx="1.969" ry="0.229"/></svg>
|
||||||
|
After Width: | Height: | Size: 870 B |
1
src/components/icons/emojis/Sick.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><defs><style>.a{fill:#009345;}.b{fill:#017b3f;}.c{fill:#08512a;}</style></defs><rect class="a" x="1" y="1" width="22" height="22" rx="7.656"/><path class="b" d="M23,13.938a14.69,14.69,0,0,1-12.406,6.531c-5.542,0-6.563-1-9.142-2.529A7.66,7.66,0,0,0,8.656,23h6.688A7.656,7.656,0,0,0,23,15.344Z"/><path class="c" d="M9.6,8.833,9.021,8.6c-.35-.144-.7-.283-1.058-.412s-.716-.251-1.08-.362-.731-.212-1.1-.3l-.012,0a.246.246,0,0,0-.186.448l.01.006c.325.2.656.392.991.573q.281.15.564.291a.245.245,0,0,1,0,.439q-.285.141-.564.292c-.335.18-.667.369-.992.573l-.016.01a.246.246,0,0,0,.187.447l.018,0c.374-.088.741-.19,1.105-.3s.723-.234,1.079-.362c.179-.064.355-.134.532-.2l.526-.213.573-.232A.246.246,0,0,0,9.6,8.833Z"/><path class="c" d="M14.405,8.833l.574-.235c.35-.144.7-.283,1.058-.412s.716-.251,1.08-.362.731-.212,1.1-.3l.012,0a.246.246,0,0,1,.186.448l-.01.006c-.325.2-.656.392-.991.573q-.28.15-.564.291a.245.245,0,0,0,0,.439q.285.141.564.292c.335.18.667.369.992.573l.016.01a.246.246,0,0,1-.187.447l-.018,0c-.374-.088-.741-.19-1.105-.3s-.723-.234-1.079-.362c-.179-.064-.355-.134-.532-.2l-.526-.213-.573-.232A.246.246,0,0,1,14.405,8.833Z"/><path class="c" d="M17.051,13.32c-.139-.122-.276-.247-.418-.366-.28-.241-.566-.476-.852-.708h0a.216.216,0,0,0-.245-.019l-.034.019c-.319.185-.636.372-.951.564-.2.119-.394.241-.59.364a.218.218,0,0,1-.243-.009l-.134-.1c-.149-.109-.3-.214-.449-.322-.3-.214-.6-.422-.9-.632l-.106-.074a.217.217,0,0,0-.248,0l-.106.074c-.3.21-.606.417-.9.632-.15.107-.3.212-.449.321l-.134.1a.218.218,0,0,1-.243.008c-.2-.122-.391-.244-.589-.363-.157-.1-.316-.19-.474-.285s-.319-.186-.478-.279l-.033-.019a.214.214,0,0,0-.245.019h0c-.287.232-.572.467-.853.709-.141.119-.278.244-.418.366s-.275.249-.41.377c.168-.08.335-.161.5-.247s.33-.169.492-.258c.228-.121.453-.247.677-.374a.217.217,0,0,1,.242.02l.2.16c.145.113.289.228.436.339.291.225.587.446.882.665l.074.055a.215.215,0,0,0,.246.008l.1-.063.464-.3c.155-.1.307-.2.461-.3.19-.124.377-.25.565-.378a.219.219,0,0,1,.243,0c.187.127.374.254.564.377.154.1.306.2.462.3l.464.3.1.063a.215.215,0,0,0,.246-.008L14.03,14c.295-.219.59-.44.882-.665.214-.165.426-.332.638-.5a.215.215,0,0,1,.241-.019c.225.127.451.253.68.376.162.089.328.171.492.258s.331.167.5.247C17.327,13.569,17.191,13.442,17.051,13.32Z"/><path class="c" d="M17.051,12.78c-.139.122-.276.247-.418.366-.28.241-.566.476-.852.708h0a.218.218,0,0,1-.245.019l-.034-.019c-.319-.185-.636-.372-.951-.564-.2-.119-.394-.241-.59-.364a.218.218,0,0,0-.243.009l-.134.1c-.149.109-.3.214-.449.321-.3.215-.6.423-.9.633l-.106.074a.217.217,0,0,1-.248,0l-.106-.074c-.3-.21-.606-.417-.9-.632-.15-.107-.3-.212-.449-.321l-.134-.1a.218.218,0,0,0-.243-.008c-.2.122-.391.244-.589.363-.157.1-.316.19-.474.285s-.319.186-.478.279l-.033.019a.214.214,0,0,1-.245-.019h0c-.287-.232-.572-.467-.853-.709-.141-.119-.278-.244-.418-.366s-.275-.249-.41-.377c.168.08.335.161.5.247s.33.169.492.258c.228.121.453.247.677.374a.217.217,0,0,0,.242-.02c.067-.054.135-.107.2-.16.145-.113.289-.228.436-.339.291-.225.587-.446.882-.665l.074-.055a.217.217,0,0,1,.246-.009l.1.064.464.3c.155.1.307.2.461.3.19.124.377.25.565.377a.217.217,0,0,0,.243,0c.187-.127.374-.254.564-.377.154-.1.306-.2.462-.3l.464-.3.1-.062a.215.215,0,0,1,.246.008l.074.054c.295.22.59.441.882.666.214.165.426.332.638.5a.215.215,0,0,0,.241.019c.225-.127.451-.253.68-.376.162-.089.328-.171.492-.258s.331-.167.5-.247C17.327,12.531,17.191,12.658,17.051,12.78Z"/></svg>
|
||||||
|
After Width: | Height: | Size: 3.4 KiB |
1
src/components/icons/emojis/Silent.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><defs><style>.a{fill:#f8de40;}.b{fill:#864e20;}.c{fill:#e7c930;}</style></defs><rect class="a" x="1" y="1" width="22" height="22" rx="7.656"/><path class="b" d="M7.055,7.313A1.747,1.747,0,1,0,8.8,9.059,1.747,1.747,0,0,0,7.055,7.313Z"/><path class="b" d="M16.958,7.313A1.747,1.747,0,1,0,18.7,9.059,1.747,1.747,0,0,0,16.958,7.313Z"/><path class="c" d="M23,13.938a14.69,14.69,0,0,1-12.406,6.531c-5.542,0-6.563-1-9.142-2.529A7.66,7.66,0,0,0,8.656,23h6.688A7.656,7.656,0,0,0,23,15.344Z"/><path class="b" d="M12.991,13.937l1.091-1.09a.555.555,0,0,0,0-.785l-.206-.207a.556.556,0,0,0-.785,0L12,12.946l-1.091-1.091a.556.556,0,0,0-.785,0l-.206.207a.555.555,0,0,0,0,.785l1.091,1.09L9.918,15.028a.555.555,0,0,0,0,.785l.206.207a.556.556,0,0,0,.785,0L12,14.929l1.091,1.091a.556.556,0,0,0,.785,0l.206-.207a.555.555,0,0,0,0-.785Z"/></svg>
|
||||||
|
After Width: | Height: | Size: 882 B |
1
src/components/icons/emojis/Smirk.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><defs><style>.a{fill:#f8de40;}.b{fill:#864e20;}.c{fill:#e7c930;}</style></defs><rect class="a" x="1" y="1" width="22" height="22" rx="7.656"/><path class="b" d="M7.055,7.313A1.747,1.747,0,1,0,8.8,9.059,1.747,1.747,0,0,0,7.055,7.313Z"/><path class="b" d="M16.958,7.313A1.747,1.747,0,1,0,18.7,9.059,1.747,1.747,0,0,0,16.958,7.313Z"/><path class="c" d="M23,13.938a14.69,14.69,0,0,1-12.406,6.531c-5.542,0-6.563-1-9.142-2.529A7.66,7.66,0,0,0,8.656,23h6.688A7.656,7.656,0,0,0,23,15.344Z"/><path class="b" d="M16.53,12.324a8.617,8.617,0,0,1-.494.726,5.59,5.59,0,0,1-1.029,1.058,4.794,4.794,0,0,1-.6.412,1.6,1.6,0,0,1-.162.091c-.055.028-.109.061-.164.09-.115.051-.226.115-.346.163-.26.119-.533.223-.819.329a.231.231,0,0,0,.055.446,3.783,3.783,0,0,0,.979-.022,3.484,3.484,0,0,0,.878-.25,3.718,3.718,0,0,0,.409-.205l.012-.007a4.1,4.1,0,0,0,.379-.26,3.51,3.51,0,0,0,1.1-1.465,3.381,3.381,0,0,0,.222-.871c0-.031.006-.061.009-.092A.231.231,0,0,0,16.53,12.324Z"/></svg>
|
||||||
|
After Width: | Height: | Size: 1015 B |
1
src/components/icons/emojis/Tears.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><defs><style>.a{fill:#f8de40;}.b{fill:#864e20;}.c{fill:#e7c930;}.d{fill:#f06880;}.e{fill:#26a9e0;}</style></defs><rect class="a" x="1" y="1" width="22" height="22" rx="7.656"/><path class="b" d="M8.907,9.844a.182.182,0,0,1-.331.1,2.016,2.016,0,0,0-.569-.567,1.731,1.731,0,0,0-1.915,0,2.016,2.016,0,0,0-.571.569.182.182,0,0,1-.331-.1,1.632,1.632,0,0,1,.346-1.023,1.927,1.927,0,0,1,3.026,0A1.64,1.64,0,0,1,8.907,9.844Z"/><path class="b" d="M18.81,9.844a.182.182,0,0,1-.331.1,2.026,2.026,0,0,0-.568-.567,1.732,1.732,0,0,0-1.916,0,2.016,2.016,0,0,0-.571.569.182.182,0,0,1-.331-.1,1.632,1.632,0,0,1,.346-1.023,1.927,1.927,0,0,1,3.026,0A1.64,1.64,0,0,1,18.81,9.844Z"/><path class="c" d="M23,13.938a14.688,14.688,0,0,1-12.406,6.531c-5.542,0-6.563-1-9.142-2.529A7.66,7.66,0,0,0,8.656,23h6.688A7.656,7.656,0,0,0,23,15.344Z"/><path class="b" d="M16.666,12.583H7.334a.493.493,0,0,0-.492.544c.123,1.175.875,3.842,5.158,3.842s5.035-2.667,5.158-3.842A.493.493,0,0,0,16.666,12.583Z"/><path class="d" d="M12,16.969a6.538,6.538,0,0,0,2.959-.6,1.979,1.979,0,0,0-1.209-.853c-1.344-.3-1.75.109-1.75.109s-.406-.406-1.75-.109a1.979,1.979,0,0,0-1.209.853A6.538,6.538,0,0,0,12,16.969Z"/><path class="e" d="M5.117,15.682a6.6,6.6,0,0,0,1.311-4.356,6.6,6.6,0,0,0-4.357,1.31c-1.77,1.523-.92,3.011-.442,3.489S3.594,17.453,5.117,15.682Z"/><path class="e" d="M18.883,15.682a6.6,6.6,0,0,1-1.311-4.356,6.6,6.6,0,0,1,4.357,1.31c1.77,1.523.92,3.011.442,3.489S20.406,17.453,18.883,15.682Z"/></svg>
|
||||||
|
After Width: | Height: | Size: 1.5 KiB |
1
src/components/icons/emojis/ThumbsUp.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d="M512 224.112C512 197.608 490.516 176.133 464 176.133H317.482C340.25 138.226 352.005 95.257 352.005 80.11C352.005 56.523 333.495 32 302.54 32C239.411 32 276.176 108.148 194.312 173.618L178.016 186.644C166.23 196.06 160.285 209.903 160.215 223.897C160.191 223.921 160 224.112 160 224.112V384.042C160 399.146 167.113 413.368 179.198 422.427L213.336 448.02C241.027 468.779 274.702 480 309.309 480H368C394.516 480 416 458.525 416 432.021C416 428.386 415.52 424.878 414.754 421.475C434 415.228 448 397.37 448 376.045C448 366.897 445.303 358.438 440.861 351.164C463.131 347.002 480 327.547 480 304.077C480 291.577 475.107 280.298 467.275 271.761C492.234 270.051 512 249.495 512 224.112Z" class="fa-secondary"/><path d="M128 448V224C128 206.328 113.674 192 96 192H32C14.326 192 0 206.328 0 224V448C0 465.674 14.326 480 32 480H96C113.674 480 128 465.674 128 448Z" class="fa-primary"/></svg>
|
||||||
|
After Width: | Height: | Size: 1005 B |
1
src/components/icons/emojis/Tongue.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><defs><style>.a{fill:#f8de40;}.b{fill:#e7c930;}.c{fill:#864e20;}.d{fill:#f06880;}.e{fill:#cd4b68;}</style></defs><rect class="a" x="1" y="1" width="22" height="22" rx="7.656"/><path class="b" d="M23,13.938a14.69,14.69,0,0,1-12.406,6.531c-5.542,0-6.563-1-9.142-2.529A7.66,7.66,0,0,0,8.656,23h6.688A7.656,7.656,0,0,0,23,15.344Z"/><path class="c" d="M16.666,12.583H7.334a.493.493,0,0,0-.492.544c.123,1.175.875,3.842,5.158,3.842s5.035-2.667,5.158-3.842A.493.493,0,0,0,16.666,12.583Z"/><path class="d" d="M15.405,15.136a2.463,2.463,0,0,0-1.655-1.87c-1.344-.3-1.75.109-1.75.109s-.406-.406-1.75-.109A2.463,2.463,0,0,0,8.6,15.136a8.449,8.449,0,0,0,0,2.723c.264,1.172,1.061,1.61,3.4,1.61s3.141-.438,3.4-1.61A8.449,8.449,0,0,0,15.405,15.136Z"/><path class="e" d="M12.188,15.688a5.582,5.582,0,0,1,.624-2.529,1.228,1.228,0,0,0-.812.216,1.228,1.228,0,0,0-.812-.216,5.582,5.582,0,0,1,.624,2.529C11.771,17,12,17,12,17S12.229,17,12.188,15.688Z"/><path class="c" d="M9.6,8.833,9.021,8.6c-.35-.144-.7-.283-1.058-.412s-.716-.251-1.08-.362-.731-.212-1.1-.3l-.012,0a.246.246,0,0,0-.186.448l.01.006c.325.2.656.392.991.573q.281.15.564.291a.245.245,0,0,1,0,.439q-.285.141-.564.292c-.335.18-.667.369-.992.573l-.016.01a.246.246,0,0,0,.187.447l.018,0c.374-.088.741-.19,1.105-.3s.723-.234,1.079-.362c.179-.064.355-.134.532-.2l.526-.213.573-.232A.246.246,0,0,0,9.6,8.833Z"/><path class="c" d="M14.405,8.833l.574-.235c.35-.144.7-.283,1.058-.412s.716-.251,1.08-.362.731-.212,1.1-.3l.012,0a.246.246,0,0,1,.186.448l-.01.006c-.325.2-.656.392-.991.573q-.28.15-.564.291a.245.245,0,0,0,0,.439q.285.141.564.292c.335.18.667.369.992.573l.016.01a.246.246,0,0,1-.187.447l-.018,0c-.374-.088-.741-.19-1.105-.3s-.723-.234-1.079-.362c-.179-.064-.355-.134-.532-.2l-.526-.213-.573-.232A.246.246,0,0,1,14.405,8.833Z"/></svg>
|
||||||
|
After Width: | Height: | Size: 1.8 KiB |
1
src/components/icons/emojis/UpsideDown.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><defs><style>.a{fill:#f8de40;}.b{fill:#864e20;}.c{fill:#e7c930;}</style></defs><rect class="a" x="1" y="1" width="22" height="22" rx="7.656"/><path class="b" d="M7.055,16.688A1.747,1.747,0,1,1,8.8,14.941,1.748,1.748,0,0,1,7.055,16.688Z"/><path class="b" d="M16.958,16.688A1.747,1.747,0,1,1,18.7,14.941,1.748,1.748,0,0,1,16.958,16.688Z"/><path class="b" d="M14,12.793a.32.32,0,0,1-.313-.327,2.1,2.1,0,0,0-.5-1.33A1.593,1.593,0,0,0,12,10.7a1.6,1.6,0,0,0-1.187.43,2.088,2.088,0,0,0-.5,1.334.32.32,0,1,1-.64.012,2.712,2.712,0,0,1,.679-1.791A2.211,2.211,0,0,1,12,10.063a2.211,2.211,0,0,1,1.647.625,2.718,2.718,0,0,1,.679,1.791A.322.322,0,0,1,14,12.793Z"/><path class="c" d="M23,13.938a14.69,14.69,0,0,1-12.406,6.531c-5.542,0-6.563-1-9.142-2.529A7.66,7.66,0,0,0,8.656,23h6.688A7.656,7.656,0,0,0,23,15.344Z"/></svg>
|
||||||
|
After Width: | Height: | Size: 868 B |
1
src/components/icons/emojis/Worried.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><defs><style>.a{fill:#f8de40;}.b{fill:#864e20;}.c{fill:#e7c930;}.d{fill:#f06880;}</style></defs><rect class="a" x="1" y="1" width="22" height="22" rx="7.656"/><path class="b" d="M7.055,7.313A1.747,1.747,0,1,0,8.8,9.059,1.747,1.747,0,0,0,7.055,7.313Z"/><path class="b" d="M16.958,7.313A1.747,1.747,0,1,0,18.7,9.059,1.747,1.747,0,0,0,16.958,7.313Z"/><path class="c" d="M23,13.938a14.69,14.69,0,0,1-12.406,6.531c-5.542,0-6.563-1-9.142-2.529A7.66,7.66,0,0,0,8.656,23h6.688A7.656,7.656,0,0,0,23,15.344Z"/><path class="b" d="M16.083,12.556A5.487,5.487,0,0,0,12,10.806a5.487,5.487,0,0,0-4.083,1.75c-.959,1.292-.147,2.667.885,2.583s2.781-.285,3.2-.285,2.167.2,3.2.285S17.042,13.848,16.083,12.556Z"/><path class="d" d="M13.75,13.266c-1.344-.3-1.75.109-1.75.109s-.406-.406-1.75-.109A2.463,2.463,0,0,0,8.6,15.136a1.1,1.1,0,0,0,.207,0c1.031-.083,2.781-.285,3.2-.285s2.167.2,3.2.285a1.1,1.1,0,0,0,.207,0A2.463,2.463,0,0,0,13.75,13.266Z"/><path class="c" d="M13.965,15.91a9.842,9.842,0,0,0-1.965-.3,9.842,9.842,0,0,0-1.965.3c-.294.061-.3.3,0,.261S12,16.041,12,16.041s1.663.09,1.965.13S14.259,15.971,13.965,15.91Z"/><path class="b" d="M19.686,6.658l0,0a2.954,2.954,0,0,0-.228-.385,4.467,4.467,0,0,0-.576-.675c-.108-.1-.217-.205-.332-.3s-.242-.174-.364-.26A3.4,3.4,0,0,0,17.8,4.8c-.134-.066-.263-.143-.4-.2a4.857,4.857,0,0,0-1.743-.4,3.732,3.732,0,0,0-1.334.177.174.174,0,0,0,.007.327c.406.139.784.271,1.157.41.494.184.973.367,1.442.576.121.043.233.107.351.158l.178.076c.06.025.114.059.174.085.116.054.23.112.35.161l.011,0c.114.06.229.119.348.175.247.105.476.244.735.355.128.06.254.124.386.186A.173.173,0,0,0,19.686,6.658Z"/><path class="b" d="M9.691,4.38A3.729,3.729,0,0,0,8.357,4.2a4.862,4.862,0,0,0-1.743.4c-.139.055-.269.132-.4.2a3.4,3.4,0,0,0-.384.231c-.122.086-.246.169-.363.26s-.224.2-.332.3a4.474,4.474,0,0,0-.577.675,2.948,2.948,0,0,0-.227.385l0,0a.173.173,0,0,0,.227.236c.131-.062.258-.126.386-.186.259-.111.487-.25.734-.355.119-.056.235-.115.349-.175l.01,0c.12-.049.235-.107.35-.161.06-.026.115-.06.174-.085l.178-.076c.118-.051.231-.115.352-.158.469-.209.947-.392,1.441-.576.373-.139.751-.271,1.158-.41A.174.174,0,0,0,9.691,4.38Z"/></svg>
|
||||||
|
After Width: | Height: | Size: 2.1 KiB |
24
src/routes/deletion/life-and-lineage.tsx
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import DeletionForm from "~/components/DeletionForm";
|
||||||
|
|
||||||
|
export default function LifeAndLinageDeletionForm() {
|
||||||
|
return (
|
||||||
|
<div class="pt-20">
|
||||||
|
<div class="container mx-auto p-4 md:p-6 lg:p-12">
|
||||||
|
<div class="w-full justify-center">
|
||||||
|
<div class="text-xl">
|
||||||
|
<em>What will happen</em>:
|
||||||
|
</div>
|
||||||
|
Once you send, if a match to the email provided is found in our
|
||||||
|
system, a 24hr grace period is started where you can request a
|
||||||
|
cancellation of the account deletion. Once the grace period ends, the
|
||||||
|
account's entry in our central database will be completely
|
||||||
|
removed, and your individual database storing your remote saves will
|
||||||
|
also be deleted. No data related to the account is retained in any
|
||||||
|
way.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<DeletionForm />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ import { env } from "~/env/server";
|
|||||||
import { TRPCError } from "@trpc/server";
|
import { TRPCError } from "@trpc/server";
|
||||||
import { ConnectionFactory } from "~/server/utils";
|
import { ConnectionFactory } from "~/server/utils";
|
||||||
import * as bcrypt from "bcrypt";
|
import * as bcrypt from "bcrypt";
|
||||||
|
import { getCookie, setCookie } from "vinxi/http";
|
||||||
|
|
||||||
const assets: Record<string, string> = {
|
const assets: Record<string, string> = {
|
||||||
"shapes-with-abigail": "shapes-with-abigail.apk",
|
"shapes-with-abigail": "shapes-with-abigail.apk",
|
||||||
@@ -201,4 +202,91 @@ export const miscRouter = createTRPCRouter({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// Account Deletion Request
|
||||||
|
// ============================================================
|
||||||
|
|
||||||
|
sendDeletionRequestEmail: publicProcedure
|
||||||
|
.input(z.object({ email: z.string().email() }))
|
||||||
|
.mutation(async ({ input }) => {
|
||||||
|
// Check if deletion request was recently sent
|
||||||
|
const deletionExp = getCookie("deletionRequestSent");
|
||||||
|
let remaining = 0;
|
||||||
|
|
||||||
|
if (deletionExp) {
|
||||||
|
const expires = new Date(deletionExp);
|
||||||
|
remaining = expires.getTime() - Date.now();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remaining > 0) {
|
||||||
|
throw new TRPCError({
|
||||||
|
code: "TOO_MANY_REQUESTS",
|
||||||
|
message: "countdown not expired",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const apiKey = env.SENDINBLUE_KEY;
|
||||||
|
const apiUrl = "https://api.sendinblue.com/v3/smtp/email";
|
||||||
|
|
||||||
|
// Email to admin
|
||||||
|
const sendinblueMyData = {
|
||||||
|
sender: {
|
||||||
|
name: "freno.me",
|
||||||
|
email: "michael@freno.me",
|
||||||
|
},
|
||||||
|
to: [{ email: "michael@freno.me" }],
|
||||||
|
htmlContent: `<html><head></head><body><div>Request Name: Life and Lineage Account Deletion</div><div>Request Email: ${input.email}</div></body></html>`,
|
||||||
|
subject: "Life and Lineage Acct Deletion",
|
||||||
|
};
|
||||||
|
|
||||||
|
// Email to user
|
||||||
|
const sendinblueUserData = {
|
||||||
|
sender: {
|
||||||
|
name: "freno.me",
|
||||||
|
email: "michael@freno.me",
|
||||||
|
},
|
||||||
|
to: [{ email: input.email }],
|
||||||
|
htmlContent: `<html><head></head><body><div>Request Name: Life and Lineage Account Deletion</div><div>Account to delete: ${input.email}</div><div>You can email michael@freno.me in the next 24hrs to cancel the deletion, email with subject line "Account Deletion Cancellation"</div></body></html>`,
|
||||||
|
subject: "Life and Lineage Acct Deletion",
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Send both emails
|
||||||
|
await fetch(apiUrl, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
accept: "application/json",
|
||||||
|
"api-key": apiKey,
|
||||||
|
"content-type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify(sendinblueMyData),
|
||||||
|
});
|
||||||
|
|
||||||
|
await fetch(apiUrl, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
accept: "application/json",
|
||||||
|
"api-key": apiKey,
|
||||||
|
"content-type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify(sendinblueUserData),
|
||||||
|
});
|
||||||
|
|
||||||
|
// Set cookie to prevent spam (60 second cooldown)
|
||||||
|
const exp = new Date(Date.now() + 1 * 60 * 1000);
|
||||||
|
setCookie("deletionRequestSent", exp.toUTCString(), {
|
||||||
|
expires: exp,
|
||||||
|
path: "/",
|
||||||
|
});
|
||||||
|
|
||||||
|
return { message: "request sent" };
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
throw new TRPCError({
|
||||||
|
code: "INTERNAL_SERVER_ERROR",
|
||||||
|
message: "SMTP server error: Sorry! You can reach me at michael@freno.me",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|||||||