diff --git a/apps/cms/.env.example b/apps/cms/.env.example new file mode 100644 index 00000000..14e24ee0 --- /dev/null +++ b/apps/cms/.env.example @@ -0,0 +1,7 @@ +NEXT_PUBLIC_FIREBASE_API_KEY= +NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN= +NEXT_PUBLIC_FIREBASE_DATABASE_URL= +NEXT_PUBLIC_FIREBASE_PROJECT_ID= +NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET= +NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID= +NEXT_PUBLIC_FIREBASE_APP_ID= diff --git a/libs/ui-components/src/Button.tsx b/libs/ui-components/src/Button.tsx index 0819bf02..af9004cc 100644 --- a/libs/ui-components/src/Button.tsx +++ b/libs/ui-components/src/Button.tsx @@ -1,24 +1,54 @@ -import React, {useState} from "react"; +import clsx from "clsx"; +import React, {useEffect, useState} from "react"; interface ButtonProps { title: string; - onClick: () => Promise | void; - style?: "normal" | "rounded" | "outline" | "outline-rounded" | "icon" | "icon-rounded"; + onClick?: () => Promise | void; + style?: "normal" | "plain-text" | "rounded" | "outline" | "outline-rounded" | "icon" | "icon-rounded"; color?: "primary" | "meta-3" | "black"; + type?: "button" | "reset" | "submit"; + className?: string[]; + loading?: boolean; + disabled?: boolean; children?: React.ReactNode; } -export function Button({title, onClick, style = "rounded", color = "primary", children}: ButtonProps) { - const [isLoading, setIsLoading] = useState(false); +export function Button(props: ButtonProps) { + const { + title, + onClick, + style = "rounded", + color = "primary", + children, + loading = false, + disabled = false, + type, + className = [], + } = props; - const handleClick = async () => { - setIsLoading(true); - try { - await onClick(); - } finally { - setIsLoading(false); - } - }; + const [isLoading, setIsLoading] = useState(loading); + const [isDisabled, setIsDisabled] = useState(disabled); + + useEffect(() => { + return () => pruneState(); + }, []); + + useEffect(() => { + setIsLoading(loading); + + return () => pruneState(); + }, [loading]); + + useEffect(() => { + setIsDisabled(disabled); + + return () => pruneState(); + }, [disabled]); + + function pruneState() { + setIsLoading(false); + setIsDisabled(false); + } let styles = [ "inline-flex", @@ -29,7 +59,7 @@ export function Button({title, onClick, style = "rounded", color = "primary", ch "text-center", "font-medium", "hover:bg-opacity-90", - isLoading ? "opacity-50 cursor-not-allowed" : "", + isLoading || isDisabled ? "disabled:opacity-50 opacity-50 cursor-not-allowed" : "", ]; switch (color) { @@ -49,6 +79,10 @@ export function Button({title, onClick, style = "rounded", color = "primary", ch switch (style) { case "normal": break; + case "plain-text": + styles = styles.filter((style) => style !== "text-white"); + styles.push("!bg-transparent", `hover:text-${color}`); + break; case "rounded": styles.push("rounded-md"); break; @@ -69,10 +103,39 @@ export function Button({title, onClick, style = "rounded", color = "primary", ch break; } + styles = styles.concat(styles, ...className); + return ( - ); }