-
Notifications
You must be signed in to change notification settings - Fork 2
feat(web,cms): add quiz-button section component #443
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
15b6891
feat(cms): add quiz-button section component schema
Kneesal 281baf1
feat(web): add QuizButton section component with modal
Kneesal 32f2330
feat(cms): add quiz-button seed data in bootstrap
Kneesal 45e14ea
fix(cms): move quiz-button seed into existing seed scripts
Kneesal 68685db
fix(cms): remove quiz-button from mobile seed script
Kneesal 3e4bb6d
fix: remove quiz-button from scripts/seed-easter.mjs
Kneesal 3be3903
fix(cms): patch graphql-depth-limit null node crash
Kneesal 25ddbff
Revert "fix(cms): patch graphql-depth-limit null node crash"
Kneesal 15c407c
fix(cms): disable graphql depth limit to avoid crash
Kneesal f0cb5d6
fix(web,cms): fix quiz-button fragment composition and depth limit
Kneesal d076f35
fix(web): inline quiz button fields in section fragment
Kneesal 4387503
fix(web): port exact quiz button styles from original component
Kneesal d45beaa
fix(web): render quiz modal via portal for true fullscreen
Kneesal 1b97552
fix(web): use shadcn Dialog portal for fullscreen quiz modal
Kneesal 51b204f
feat(cms): add quiz button seed data to easter experience
Kneesal f43edb1
fix(web,cms): address PR review feedback for quiz button
Kneesal File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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
This file contains hidden or 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
This file contains hidden or 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
This file contains hidden or 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 @@ | ||
| { | ||
| "collectionName": "components_sections_quiz_buttons", | ||
| "info": { | ||
| "displayName": "Quiz Button", | ||
| "icon": "question-circle", | ||
| "description": "Interactive quiz button that opens a modal with an embedded quiz iframe" | ||
| }, | ||
| "options": {}, | ||
| "attributes": { | ||
| "buttonText": { | ||
| "type": "string", | ||
| "required": true | ||
| }, | ||
| "iframeSrc": { | ||
| "type": "string", | ||
| "required": true, | ||
| "regex": "^https://[\\w.-]+\\.nextstep\\.is/.*$" | ||
| } | ||
| } | ||
| } |
This file contains hidden or 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
This file contains hidden or 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
This file contains hidden or 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,78 @@ | ||
| "use client" | ||
|
|
||
| import { type ReactElement, useState } from "react" | ||
| import { Loader2, XIcon } from "lucide-react" | ||
| import { Dialog, DialogClose, DialogContent } from "@/components/ui/dialog" | ||
|
|
||
| type QuizButtonData = { | ||
| id: string | ||
| buttonText: string | ||
| iframeSrc: string | ||
| } | ||
|
|
||
| type QuizButtonProps = { | ||
| data: QuizButtonData | ||
| } | ||
|
|
||
| export function QuizButton({ data }: QuizButtonProps): ReactElement { | ||
| const { buttonText, iframeSrc } = data | ||
| const [open, setOpen] = useState(false) | ||
|
|
||
| return ( | ||
| <> | ||
| <div className="mx-auto w-full px-6 pt-12 sm:w-auto lg:w-1/2 lg:px-8 xl:w-1/2 2xl:w-2xl"> | ||
| <button | ||
| onClick={() => setOpen(true)} | ||
| className="animate-mesh-gradient hover:animate-mesh-gradient-fast group relative w-full overflow-hidden rounded-lg bg-linear-to-tr from-yellow-500 via-amber-500 to-red-700 bg-size-[400%_400%] bg-blend-multiply text-white shadow-lg hover:bg-orange-500" | ||
| aria-label="Open faith quiz" | ||
| type="button" | ||
| > | ||
| <div className="flex cursor-pointer items-center justify-between p-4 xl:p-6"> | ||
| <div className="absolute inset-0 bg-[url(/assets/overlay.svg)] bg-repeat opacity-50 mix-blend-multiply" /> | ||
| <div className="relative z-1 flex w-full items-center leading-[1.2] font-semibold md:text-xl xl:text-2xl"> | ||
| <span className="mr-4 flex-none rounded-lg border-2 border-white px-2 py-1 text-xs font-extrabold tracking-wider uppercase"> | ||
| Quiz | ||
| </span> | ||
| <div className="flex-auto text-center">{buttonText}</div> | ||
| </div> | ||
| <span className="transition"> | ||
| <svg fill="none" height="24" width="24" stroke="currentColor"> | ||
| <path | ||
| strokeLinecap="round" | ||
| strokeLinejoin="round" | ||
| strokeWidth="2" | ||
| d="M13 5l7 7m0 0l-7 7m7-7H6" | ||
| /> | ||
| </svg> | ||
| </span> | ||
| </div> | ||
| </button> | ||
| </div> | ||
|
|
||
| <Dialog open={open} onOpenChange={setOpen}> | ||
| <DialogContent | ||
| overlayClassName="bg-black/80 backdrop-blur-sm" | ||
| showCloseButton={false} | ||
| className="top-0 left-0 h-dvh w-dvw max-w-none translate-x-0 translate-y-0 gap-0 rounded-none border-0 bg-transparent p-2 pt-14 ring-0 sm:max-w-none md:p-14 md:pt-0" | ||
| > | ||
| <DialogClose className="absolute top-4 right-4 z-10 rounded-full p-2 text-white transition-colors hover:bg-white/20 [&_svg]:size-8"> | ||
| <XIcon /> | ||
| <span className="sr-only">Close</span> | ||
| </DialogClose> | ||
| <div className="absolute inset-0 -z-1 flex items-center justify-center"> | ||
| <div className="scale-200 text-white"> | ||
| <Loader2 className="animate-spin" /> | ||
| </div> | ||
| </div> | ||
| <iframe | ||
| src={iframeSrc} | ||
| sandbox="allow-forms allow-scripts allow-same-origin" | ||
| referrerPolicy="strict-origin-when-cross-origin" | ||
| className="z-1 h-full w-full border-0" | ||
| title="Next Step of Faith Quiz" | ||
| /> | ||
| </DialogContent> | ||
| </Dialog> | ||
| </> | ||
| ) | ||
| } |
This file contains hidden or 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
This file contains hidden or 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,158 @@ | ||
| "use client" | ||
|
|
||
| import * as React from "react" | ||
| import { Dialog as DialogPrimitive } from "@base-ui/react/dialog" | ||
|
|
||
| import { cn } from "@/lib/utils" | ||
| import { Button } from "@/components/ui/button" | ||
| import { XIcon } from "lucide-react" | ||
|
|
||
| function Dialog({ ...props }: DialogPrimitive.Root.Props) { | ||
| return <DialogPrimitive.Root data-slot="dialog" {...props} /> | ||
| } | ||
|
|
||
| function DialogTrigger({ ...props }: DialogPrimitive.Trigger.Props) { | ||
| return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} /> | ||
| } | ||
|
|
||
| function DialogPortal({ ...props }: DialogPrimitive.Portal.Props) { | ||
| return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} /> | ||
| } | ||
|
|
||
| function DialogClose({ ...props }: DialogPrimitive.Close.Props) { | ||
| return <DialogPrimitive.Close data-slot="dialog-close" {...props} /> | ||
| } | ||
|
|
||
| function DialogOverlay({ | ||
| className, | ||
| ...props | ||
| }: DialogPrimitive.Backdrop.Props) { | ||
| return ( | ||
| <DialogPrimitive.Backdrop | ||
| data-slot="dialog-overlay" | ||
| className={cn( | ||
| "fixed inset-0 isolate z-50 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0", | ||
| className, | ||
| )} | ||
| {...props} | ||
| /> | ||
| ) | ||
| } | ||
|
|
||
| function DialogContent({ | ||
| className, | ||
| children, | ||
| showCloseButton = true, | ||
| overlayClassName, | ||
| ...props | ||
| }: DialogPrimitive.Popup.Props & { | ||
| showCloseButton?: boolean | ||
| overlayClassName?: string | ||
| }) { | ||
| return ( | ||
| <DialogPortal> | ||
| <DialogOverlay className={overlayClassName} /> | ||
| <DialogPrimitive.Popup | ||
| data-slot="dialog-content" | ||
| className={cn( | ||
| "fixed top-1/2 left-1/2 z-50 grid w-full max-w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl bg-background p-4 text-sm ring-1 ring-foreground/10 duration-100 outline-none sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", | ||
| className, | ||
| )} | ||
| {...props} | ||
| > | ||
| {children} | ||
| {showCloseButton && ( | ||
| <DialogPrimitive.Close | ||
| data-slot="dialog-close" | ||
| render={ | ||
| <Button | ||
| variant="ghost" | ||
| className="absolute top-2 right-2" | ||
| size="icon-sm" | ||
| /> | ||
| } | ||
| > | ||
| <XIcon /> | ||
| <span className="sr-only">Close</span> | ||
| </DialogPrimitive.Close> | ||
| )} | ||
| </DialogPrimitive.Popup> | ||
| </DialogPortal> | ||
| ) | ||
| } | ||
|
|
||
| function DialogHeader({ className, ...props }: React.ComponentProps<"div">) { | ||
| return ( | ||
| <div | ||
| data-slot="dialog-header" | ||
| className={cn("flex flex-col gap-2", className)} | ||
| {...props} | ||
| /> | ||
| ) | ||
| } | ||
|
|
||
| function DialogFooter({ | ||
| className, | ||
| showCloseButton = false, | ||
| children, | ||
| ...props | ||
| }: React.ComponentProps<"div"> & { | ||
| showCloseButton?: boolean | ||
| }) { | ||
| return ( | ||
| <div | ||
| data-slot="dialog-footer" | ||
| className={cn( | ||
| "-mx-4 -mb-4 flex flex-col-reverse gap-2 rounded-b-xl border-t bg-muted/50 p-4 sm:flex-row sm:justify-end", | ||
| className, | ||
| )} | ||
| {...props} | ||
| > | ||
| {children} | ||
| {showCloseButton && ( | ||
| <DialogPrimitive.Close render={<Button variant="outline" />}> | ||
| Close | ||
| </DialogPrimitive.Close> | ||
| )} | ||
| </div> | ||
| ) | ||
| } | ||
|
|
||
| function DialogTitle({ className, ...props }: DialogPrimitive.Title.Props) { | ||
| return ( | ||
| <DialogPrimitive.Title | ||
| data-slot="dialog-title" | ||
| className={cn("text-base leading-none font-medium", className)} | ||
| {...props} | ||
| /> | ||
| ) | ||
| } | ||
|
|
||
| function DialogDescription({ | ||
| className, | ||
| ...props | ||
| }: DialogPrimitive.Description.Props) { | ||
| return ( | ||
| <DialogPrimitive.Description | ||
| data-slot="dialog-description" | ||
| className={cn( | ||
| "text-sm text-muted-foreground *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground", | ||
| className, | ||
| )} | ||
| {...props} | ||
| /> | ||
| ) | ||
| } | ||
|
|
||
| export { | ||
| Dialog, | ||
| DialogClose, | ||
| DialogContent, | ||
| DialogDescription, | ||
| DialogFooter, | ||
| DialogHeader, | ||
| DialogOverlay, | ||
| DialogPortal, | ||
| DialogTitle, | ||
| DialogTrigger, | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.