add separator, buttons

This commit is contained in:
NCanggoro 2023-10-09 16:23:08 +07:00
parent 41cb93d39f
commit 25b9877f3a
9 changed files with 171 additions and 14 deletions

View File

@ -0,0 +1,37 @@
import { TargetedEvent, CSSProperties } from "preact/compat";
import './style.css';
import { SpinnerLoading } from "../..";
interface DefaultButtonProps {
label: string
containerClassName?: string,
containerStyle?: CSSProperties,
className?: string,
style?: CSSProperties
onClick?: (event: TargetedEvent) => any,
href?: string,
isLoading?: boolean
}
const DefaultButton = (props: DefaultButtonProps) => (
<div
className={props.containerClassName}
style={props.containerStyle}
>
<a
href={props.href}
onClick={props.onClick}
className={`bg-gray default-button ${props.className ? props.className : ''}`}
style={{ paddingTop: 6, paddingBottom: 6, letterSpacing: .9, borderRadius: 7, ...props.style }}
>
{ props.isLoading ?
<SpinnerLoading style={{ verticalAlign: 'middle'}}/>
:
props.label
}
</a>
</div>
)
export default DefaultButton;

View File

@ -0,0 +1,4 @@
div a.default-button:hover {
color: white;
background-color: #575757;
}

View File

@ -0,0 +1,36 @@
import { CSSProperties, TargetedEvent } from "preact/compat";
import './style.css';
import { SpinnerLoading } from "../..";
interface DefaultButtonProps {
label: string
containerClassName?: string,
containerStyle?: CSSProperties,
className?: string,
style?: CSSProperties,
isLoading?: boolean,
onClick?: (event: TargetedEvent) => any,
href?: string,
}
const WarningButton = (props: DefaultButtonProps) => (
<div
className={props.containerClassName}
style={props.containerStyle}
>
<a
href={props.href}
onClick={props.onClick}
className={`bg-error warning-button ${props.className ? props.className : ''}`}
style={{ paddingTop: 6, paddingBottom: 6, letterSpacing: .9, borderRadius: 7, ...props.style }}
>
{props.isLoading ?
<SpinnerLoading style={{ verticalAlign: 'middle'}}/>
:
props.label
}
</a>
</div>
)
export default WarningButton;

View File

@ -0,0 +1,4 @@
div a.warning-button:hover{
color: white;
background-color: #af3030;
}

View File

@ -61,10 +61,11 @@ function Header() {
/> />
</a> </a>
{user.username && {user.username &&
<div className={'profile-dropdown-img bg-secondary text-left'} style={pageState.profileMenu ? { display: 'block'} : { display: 'none'}}> <div className={'profile-dropdown-img bg-secondary text-left'} style={pageState.profileMenu ? { display: 'block' } : { display: 'none' }}>
<a href={'/user/profile'}><div className={'p-2'}>Profile</div></a> <a href={'/user/profile'}><div className={'p-2'}>Profile</div></a>
<a href={'#'}><div className={'p-2'}>Feed</div></a> <a href={'#'}><div className={'p-2'}>Feed</div></a>
<a href={'/add-location'}><div className={'p-2'}>Add location</div></a> <a href={'/add-location'}><div className={'p-2'}>Add location</div></a>
<a href={'/add-location'}><div className={'p-2'}>Settings</div></a>
<a href={'#'} onClick={handleLogout}><div className={'p-2'}>Logout</div></a> <a href={'#'} onClick={handleLogout}><div className={'p-2'}>Logout</div></a>
{/* <div className={'p-2'}><a href={'#'}>Halo</a></div> */} {/* <div className={'p-2'}><a href={'#'}>Halo</a></div> */}
{/* <div className={'p-2'}><a href={'#'}>Halo</a></div> */} {/* <div className={'p-2'}><a href={'#'}>Halo</a></div> */}
@ -98,10 +99,11 @@ function Header() {
<div className={'profile-container'}> <div className={'profile-container'}>
<a href={user.username ? '#' : '/login'} onClick={() => user.username ? setPageState({ ...pageState, profileMenu: !pageState.profileMenu }) : ''} className={`navLink ${!dropdown ? "navLink-disabled" : ""}`}>{user.username ? user.username : 'Sign in'}</a> <a href={user.username ? '#' : '/login'} onClick={() => user.username ? setPageState({ ...pageState, profileMenu: !pageState.profileMenu }) : ''} className={`navLink ${!dropdown ? "navLink-disabled" : ""}`}>{user.username ? user.username : 'Sign in'}</a>
{user && screen.width > 600 && {user && screen.width > 600 &&
<div className={'profile-dropdown bg-secondary ml-6'} style={pageState.profileMenu ? { display: 'block' } : {display: 'none'}}> <div className={'profile-dropdown bg-secondary ml-6'} style={pageState.profileMenu ? { display: 'block' } : { display: 'none' }}>
<a href={'/add-location'}><div className={'p-1'}>Add location</div></a>
<a href={'/user/profile'}><div className={'p-1'}>Profile</div></a> <a href={'/user/profile'}><div className={'p-1'}>Profile</div></a>
<a href={'#'}><div className={'p-1'}>Feed</div></a> <a href={'#'}><div className={'p-1'}>Feed</div></a>
<a href={'/add-location'}><div className={'p-1'}>Add location</div></a> <a href={'/user/settings'}><div className={'p-1'}>Settings</div></a>
{user.is_admin && {user.is_admin &&
<a href={'/submissions'} ><div className={'p-1'}>Submissions</div></a> <a href={'/submissions'} ><div className={'p-1'}>Submissions</div></a>
} }

View File

@ -1,6 +1,13 @@
import { CSSProperties } from 'preact/compat'
import './style.css' import './style.css'
export default function SpinnerLoading() {
interface SpinnerLoadingProps {
style?: CSSProperties
className?: string
}
export default function SpinnerLoading(props: SpinnerLoadingProps) {
return ( return (
<div className={'spinner'} style={{ display: 'inline-block'}}></div> <div className={`spinner ${props.className ? props.className : ''}`} style={{ display: 'inline-block', ...props.style}}></div>
) )
} }

View File

@ -0,0 +1,37 @@
import { useRef, useEffect } from "preact/compat";
interface RefOutsideClickInterface {
onOutsideClick: Function,
children: any
}
/**
* https://stackoverflow.com/questions/32553158/detect-click-outside-react-component
*/
function useRefOutsideClick(ref: any, onOutsideClick: Function) {
useEffect(() => {
function handleClickOutside(event: MouseEvent) {
if (ref.current && !ref.current.contains(event.target)) {
onOutsideClick()
}
}
// Bind the event listener
document.addEventListener("mousedown", handleClickOutside);
return () => {
// Unbind the event listener on clean up
document.removeEventListener("mousedown", handleClickOutside);
};
}, [ref]);
}
/**
* Component that alerts if you click outside of it
*/
function RefOutsideClick(props: RefOutsideClickInterface) {
const wrapperRef = useRef(null);
useRefOutsideClick(wrapperRef, props.onOutsideClick);
return <div ref={wrapperRef}>{props.children}</div>;
}
export default RefOutsideClick;

View File

@ -0,0 +1,17 @@
type SeparatorProps = {
pageName: string,
titleStyles?: any,
titleClasses?: string
}
function TitleSeparator(props: SeparatorProps) {
return (
<div class={"flex flex-row justify-between divider mb-2"}>
<h2 className={`text-sm font-bold uppercase ${props.titleClasses}`} style={props.titleStyles}>
{props.pageName}
</h2>
</div>
)
}
export default TitleSeparator;

View File

@ -1,6 +1,13 @@
import Header from "./Header"; import Header from "./Header";
import RefOutsideClick from "./RefOutsideClick";
import WarningButton from "./Button/WarningButton";
import DefaultButton from "./Button/DefaultButton";
import SeparatorWithAnchor from "./Separator/WithAnchor"; import SeparatorWithAnchor from "./Separator/WithAnchor";
import DefaultSeparator from "./Separator/Default"; import DefaultSeparator from "./Separator/Default";
import TitleSeparator from "./Separator/TitleSeparator";
import Footer from './Footer/'; import Footer from './Footer/';
import CustomInterweave from "./CustomInterweave"; import CustomInterweave from "./CustomInterweave";
import DropdownInput from "./DropdownInput"; import DropdownInput from "./DropdownInput";
@ -9,8 +16,14 @@ import SpinnerLoading from "./Loading/Spinner";
export { export {
Header, Header,
WarningButton,
DefaultButton,
RefOutsideClick,
SeparatorWithAnchor, SeparatorWithAnchor,
DefaultSeparator, DefaultSeparator,
TitleSeparator,
Footer, Footer,
CustomInterweave, CustomInterweave,
DropdownInput, DropdownInput,