Skip to content

Commit

Permalink
add impure function
Browse files Browse the repository at this point in the history
  • Loading branch information
sundaycrafts committed Apr 12, 2023
1 parent 8eb98e3 commit 4c5043d
Show file tree
Hide file tree
Showing 5 changed files with 277 additions and 0 deletions.
72 changes: 72 additions & 0 deletions app/component/Toast.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { useEffect, useRef, useState } from "react";
import * as ToastRadix from "@radix-ui/react-toast";

export const Toast = ({ isOpen }: { isOpen: boolean }) => {
const [open, setOpen] = useState(isOpen);
const eventDateRef = useRef(new Date());
const timerRef = useRef(0);

useEffect(() => {
setOpen(isOpen);
}, [isOpen]);

useEffect(() => {
return () => clearTimeout(timerRef.current);
}, []);

return (
<ToastRadix.Provider swipeDirection="right">
<button
className="inline-flex h-[35px] items-center justify-center rounded bg-white px-[15px] text-[15px] font-medium leading-[35px] text-violet11 shadow-[0_2px_10px] shadow-blackA7 outline-none hover:bg-mauve3 focus:shadow-[0_0_0_2px] focus:shadow-black"
onClick={() => {
setOpen(false);
window.clearTimeout(timerRef.current);
timerRef.current = window.setTimeout(() => {
eventDateRef.current = oneWeekAway();
setOpen(true);
}, 100);
}}
>
Add to calendar
</button>

<ToastRadix.Root
className="data-[state=open]:animate-slideIn data-[state=closed]:animate-hide data-[swipe=end]:animate-swipeOut grid grid-cols-[auto_max-content] items-center gap-x-[15px] rounded-md bg-white p-[15px] shadow-[hsl(206_22%_7%_/_35%)_0px_10px_38px_-10px,_hsl(206_22%_7%_/_20%)_0px_10px_20px_-15px] [grid-template-areas:_'title_action'_'description_action'] data-[swipe=cancel]:translate-x-0 data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=cancel]:transition-[transform_200ms_ease-out]"
open={open}
onOpenChange={setOpen}
>
<ToastRadix.Title className="text-slate12 mb-[5px] text-[15px] font-medium [grid-area:_title]">
Accepted Terms and Conditions
</ToastRadix.Title>
<ToastRadix.Description asChild>
<p className="text-slate11 m-0 text-[13px] leading-[1.3] [grid-area:_description]">
You have accepted the terms and conditions.
</p>
</ToastRadix.Description>
<ToastRadix.Action
className="[grid-area:_action]"
asChild
altText="Goto schedule to undo"
>
<button className="inline-flex h-[25px] items-center justify-center rounded bg-green2 px-[10px] text-xs font-medium leading-[25px] text-green11 shadow-[inset_0_0_0_1px] shadow-green7 hover:shadow-[inset_0_0_0_1px] hover:shadow-green8 focus:shadow-[0_0_0_2px] focus:shadow-green8">
Ok
</button>
</ToastRadix.Action>
</ToastRadix.Root>
<ToastRadix.Viewport className="fixed bottom-0 right-0 z-[2147483647] m-0 flex w-[390px] max-w-[100vw] list-none flex-col gap-[10px] p-[var(--viewport-padding)] outline-none [--viewport-padding:_25px]" />
</ToastRadix.Provider>
);
};

function oneWeekAway() {
const now = new Date();
const inOneWeek = now.setDate(now.getDate() + 7);
return new Date(inOneWeek);
}

function prettyDate(date: Date) {

Check warning on line 67 in app/component/Toast.tsx

View workflow job for this annotation

GitHub Actions / ⬣ ESLint

'prettyDate' is defined but never used
return new Intl.DateTimeFormat("en-US", {
dateStyle: "full",
timeStyle: "short",
}).format(date);
}
20 changes: 20 additions & 0 deletions app/models/tac.server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
declare global {
var __tac__: Date | null;
}

if (!global.__tac__) {
global.__tac__ = null;
}

export async function acceptTac(tac: unknown) {
global.__tac__ = tac ? new Date() : null;
}

export async function getAcceptedTac() {
return !!global.__tac__;
}

export async function hasChanged(): Promise<boolean> {
const acceptedAt = global.__tac__?.getTime() || NaN;
return Date.now() - acceptedAt < 3_000;
}
86 changes: 86 additions & 0 deletions app/routes/impure.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import * as Checkbox from "@radix-ui/react-checkbox";
import { CheckIcon } from "@radix-ui/react-icons";
import * as SeparatorRadix from "@radix-ui/react-separator";
import { Form, useLoaderData, useSubmit } from "@remix-run/react";
import type { ActionArgs } from "@remix-run/node";
import { json, redirect } from "@remix-run/node";
import { acceptTac, getAcceptedTac, hasChanged } from "~/models/tac.server";
import { Toast } from "~/component/Toast";

function greeting(name: string) {
const hours = new Date().getHours();
if (hours < 12) {
return `Good morning ${name}!`;
} else if (hours < 18) {
return `Good afternoon ${name}!`;
} else {
return `Good night ${name}!`;
}
}

export async function loader() {
return json({
name: "user",
tacAccepted: await getAcceptedTac(),
hasChanged: await hasChanged(),
});
}

export async function action({ request }: ActionArgs) {
const formData = await request.formData();

console.debug("[Debug] tac accepted =>", formData.get("tac_accepted"));
await acceptTac(formData.get("tac_accepted"));

return redirect("/impure");
}

export default function Impure() {
const data = useLoaderData<typeof loader>();
const submit = useSubmit();

return (
<>
<div
style={{
backgroundImage:
"linear-gradient(330deg, hsl(272, 53%, 50%) 0%, hsl(226, 68%, 56%) 100%)",
}}
className={"flex h-[100vh] flex-col items-center justify-center"}
>
<div className="mx-[15px] w-full max-w-[300px]">
<div className="text-[15px] font-medium leading-5 text-white">
{greeting(data.name)}
</div>
<div className="text-[15px] leading-5 text-white">
Radix Primitives is an open-source UI component library.
</div>
<SeparatorRadix.Root className="my-[15px] bg-violet6 data-[orientation=horizontal]:h-px data-[orientation=vertical]:h-full data-[orientation=horizontal]:w-full data-[orientation=vertical]:w-px" />

<Form method={"post"} onChange={(e) => submit(e.currentTarget)}>
<div className="flex items-center">
<Checkbox.Root
className="flex h-[25px] w-[25px] appearance-none items-center justify-center rounded-[4px] bg-white shadow-[0_2px_10px] shadow-blackA7 outline-none hover:bg-violet3 focus:shadow-[0_0_0_2px_black]"
defaultChecked={data.tacAccepted}
name={"tac_accepted"}
id="c1"
>
<Checkbox.Indicator className="text-violet11">
<CheckIcon />
</Checkbox.Indicator>
</Checkbox.Root>
<label
className="pl-[15px] text-[15px] leading-none text-white"
htmlFor="c1"
>
Accept terms and conditions.
</label>
</div>
</Form>
</div>
</div>

<Toast isOpen={data.hasChanged} />
</>
);
}
96 changes: 96 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,12 @@
"dependencies": {
"@prisma/client": "^4.11.0",
"@radix-ui/colors": "^0.1.8",
"@radix-ui/react-checkbox": "^1.0.3",
"@radix-ui/react-dialog": "^1.0.3",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-separator": "^1.0.2",
"@radix-ui/react-tabs": "^1.0.3",
"@radix-ui/react-toast": "^1.1.3",
"@remix-run/node": "^1.15.0",
"@remix-run/react": "^1.15.0",
"@remix-run/serve": "^1.15.0",
Expand Down

0 comments on commit 4c5043d

Please sign in to comment.