-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
8eb98e3
commit 4c5043d
Showing
5 changed files
with
277 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) { | ||
return new Intl.DateTimeFormat("en-US", { | ||
dateStyle: "full", | ||
timeStyle: "short", | ||
}).format(date); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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} /> | ||
</> | ||
); | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters