feat: redo settings and all org pages. (#601)
* feat: new components, deploy storybook * refactor: simplify component field definitions and enhance button loading state - Removed unnecessary type imports and simplified the FIELDS array definitions across multiple components in Storybook. - Updated button component to use a loading state instead of isLoading, improving clarity and consistency in props. - Adjusted button stories to reflect the new loading prop and enhanced the button's loading visual feedback. - Minor CSS adjustments for better layout and styling consistency. * chore: add field, card, password components * feat: improve page component & update AuthUI path * chore: update bits-ui to version 2.14.4 and all org related UI's - Updated bits-ui dependency in pnpm-lock.yaml and package.json to version 2.14.4. - Refactored imports for RoleBasedSecurity and UpgradeBanner components to use the new ui feature directory. - Removed unused Course components and related files to clean up the codebase. - Enhanced various components to improve consistency and maintainability. * chore: move all setting buttons to the top and update auth ui styles * chore: remove svelte-loading-spinners and replace with @cio/ui/base/spinner - Removed all instances of svelte-loading-spinners from the project. - Updated components to use the new Spinner from @cio/ui/base/spinner. - Cleaned up pnpm-lock.yaml and package.json to reflect the removal of svelte-loading-spinners. - Added new CSS animations for rocket launch effects in app.css. - Enhanced email change flow with updated verification messages in translations. * chore: remove supabase file upload from dashboard and move to r2 * chore: update organization API and UI components - Added new API methods for organization plan operations and team management. - Introduced middleware for API key authentication and organization admin checks. - Refactored organization-related components to utilize the new API structure. - Updated various UI components to improve consistency and maintainability. - Enhanced error handling and validation for organization-related actions. - Removed deprecated services and streamlined the codebase.
This commit is contained in:
@@ -1,21 +1,20 @@
|
||||
<script lang="ts" module>
|
||||
import { cn, type WithElementRef } from '../../tools';
|
||||
import type { WithChildren, WithoutChildren } from 'bits-ui';
|
||||
import type { HTMLAnchorAttributes, HTMLButtonAttributes } from 'svelte/elements';
|
||||
import { type VariantProps, tv } from 'tailwind-variants';
|
||||
import { Spinner } from '../spinner';
|
||||
|
||||
export const buttonVariants = tv({
|
||||
base: "ui:focus-visible:border-ring ui:cursor-pointer ui:focus-visible:ring-ring/50 ui:aria-invalid:ring-destructive/20 ui:dark:aria-invalid:ring-destructive/40 ui:aria-invalid:border-destructive ui:inline-flex ui:shrink-0 ui:items-center ui:justify-center ui:gap-2 ui:whitespace-nowrap ui:rounded-md ui:text-sm ui:font-medium ui:outline-none ui:transition-all ui:focus-visible:ring-[3px] ui:disabled:pointer-events-none ui:disabled:opacity-50 ui:aria-disabled:pointer-events-none ui:aria-disabled:opacity-50 ui:[&_svg:not([class*='size-'])]:size-4 ui:[&_svg]:pointer-events-none ui:[&_svg]:shrink-0",
|
||||
base: "ui:aria-invalid:ring-destructive/20 ui:dark:aria-invalid:ring-destructive/40 ui:aria-invalid:border-destructive ui:focus-visible:border-ring ui:focus-visible:ring-ring/50 ui:relative ui:inline-flex ui:shrink-0 ui:items-center ui:justify-center ui:gap-2 ui:overflow-hidden ui:rounded-md ui:text-sm ui:font-medium ui:whitespace-nowrap ui:outline-hidden ui:transition-all ui:select-none ui:focus-visible:ring-[3px] ui:disabled:pointer-events-none ui:disabled:opacity-50 ui:[&_svg]:pointer-events-none ui:[&_svg]:shrink-0 ui:[&_svg:not([class*='size-'])]:size-4 ui:cursor-pointer",
|
||||
variants: {
|
||||
variant: {
|
||||
default: 'ui:bg-primary ui:text-primary-foreground ui:shadow-xs ui:hover:bg-primary/90',
|
||||
default: 'ui:bg-primary ui:text-primary-foreground ui:[a&]:hover:bg-primary/90 ui:shadow-2xs',
|
||||
destructive:
|
||||
'ui:bg-destructive ui:shadow-xs ui:hover:bg-destructive/90 ui:focus-visible:ring-destructive/20 ui:dark:focus-visible:ring-destructive/40 ui:dark:bg-destructive/60 ui:text-white',
|
||||
'ui:bg-destructive ui:[a&]:hover:bg-destructive/90 ui:focus-visible:ring-destructive/20 ui:dark:bg-destructive/60 ui:dark:focus-visible:ring-destructive/40 ui:text-white ui:shadow-2xs',
|
||||
outline:
|
||||
'ui:bg-background ui:shadow-xs ui:hover:bg-accent ui:hover:text-accent-foreground ui:dark:bg-input/30 ui:dark:border-input ui:dark:hover:bg-input/50 ui:border',
|
||||
secondary: 'ui:bg-secondary ui:text-secondary-foreground ui:shadow-xs ui:hover:bg-secondary/80',
|
||||
ghost: 'ui:hover:bg-accent ui:hover:text-accent-foreground ui:dark:hover:bg-accent/50',
|
||||
link: 'ui:text-primary ui:underline-offset-4 ui:hover:underline'
|
||||
'ui:bg-background ui:[a&]:hover:bg-accent ui:[a&]:hover:text-accent-foreground ui:dark:border-input ui:dark:bg-input/30 ui:dark:hover:bg-input/50 ui:border ui:shadow-2xs',
|
||||
secondary: 'ui:bg-secondary ui:text-secondary-foreground ui:[a&]:hover:bg-secondary/80 ui:shadow-2xs',
|
||||
ghost: 'ui:[a&]:hover:bg-accent ui:[a&]:hover:text-accent-foreground ui:dark:[a&]:hover:bg-accent/50',
|
||||
link: 'ui:text-primary ui:underline-offset-4 ui:[a&]:hover:underline'
|
||||
},
|
||||
size: {
|
||||
default: 'ui:h-9 ui:px-4 ui:py-2 ui:has-[>svg]:px-3',
|
||||
@@ -35,58 +34,93 @@
|
||||
export type ButtonVariant = VariantProps<typeof buttonVariants>['variant'];
|
||||
export type ButtonSize = VariantProps<typeof buttonVariants>['size'];
|
||||
|
||||
export type ButtonProps = WithElementRef<HTMLButtonAttributes> &
|
||||
WithElementRef<HTMLAnchorAttributes> & {
|
||||
variant?: ButtonVariant;
|
||||
size?: ButtonSize;
|
||||
isLoading?: boolean;
|
||||
export type ButtonPropsWithoutHTML = WithChildren<{
|
||||
ref?: HTMLElement | null;
|
||||
variant?: ButtonVariant;
|
||||
size?: ButtonSize;
|
||||
loading?: boolean;
|
||||
onClickPromise?: (
|
||||
e: MouseEvent & {
|
||||
currentTarget: EventTarget & HTMLButtonElement;
|
||||
}
|
||||
) => Promise<void>;
|
||||
}>;
|
||||
|
||||
export type AnchorElementProps = ButtonPropsWithoutHTML &
|
||||
WithoutChildren<Omit<HTMLAnchorAttributes, 'href' | 'type'>> & {
|
||||
href: HTMLAnchorAttributes['href'];
|
||||
type?: never;
|
||||
disabled?: HTMLButtonAttributes['disabled'];
|
||||
};
|
||||
|
||||
export type ButtonElementProps = ButtonPropsWithoutHTML &
|
||||
WithoutChildren<Omit<HTMLButtonAttributes, 'type' | 'href'>> & {
|
||||
type?: HTMLButtonAttributes['type'];
|
||||
href?: never;
|
||||
disabled?: HTMLButtonAttributes['disabled'];
|
||||
};
|
||||
|
||||
export type ButtonProps = AnchorElementProps | ButtonElementProps;
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { cn } from '../../tools';
|
||||
import LoaderCircleIcon from '@lucide/svelte/icons/loader-circle';
|
||||
|
||||
let {
|
||||
class: className,
|
||||
ref = $bindable(null),
|
||||
variant = 'default',
|
||||
size = 'default',
|
||||
ref = $bindable(null),
|
||||
href = undefined,
|
||||
isLoading = false,
|
||||
type = 'button',
|
||||
loading = false,
|
||||
disabled = false,
|
||||
tabindex = 0,
|
||||
onclick,
|
||||
onClickPromise,
|
||||
class: className,
|
||||
children,
|
||||
...restProps
|
||||
...rest
|
||||
}: ButtonProps = $props();
|
||||
|
||||
let disabled = $derived(restProps.disabled || isLoading);
|
||||
</script>
|
||||
|
||||
{#if href}
|
||||
<a
|
||||
bind:this={ref}
|
||||
data-slot="button"
|
||||
class={cn(buttonVariants({ variant, size }), className)}
|
||||
href={disabled ? undefined : href}
|
||||
aria-disabled={disabled}
|
||||
role={disabled ? 'link' : undefined}
|
||||
tabindex={disabled ? -1 : undefined}
|
||||
{...restProps}
|
||||
>
|
||||
{#if isLoading}
|
||||
<Spinner />
|
||||
{/if}
|
||||
{@render children?.()}
|
||||
</a>
|
||||
{:else}
|
||||
<button
|
||||
bind:this={ref}
|
||||
data-slot="button"
|
||||
class={cn(buttonVariants({ variant, size }), className)}
|
||||
{type}
|
||||
{disabled}
|
||||
{...restProps}
|
||||
>
|
||||
{#if isLoading}
|
||||
<Spinner />
|
||||
{/if}
|
||||
{@render children?.()}
|
||||
</button>
|
||||
{/if}
|
||||
<!-- This approach to disabled links is inspired by bits-ui see: https://github.com/huntabyte/bits-ui/pull/1055 -->
|
||||
<svelte:element
|
||||
this={href ? 'a' : 'button'}
|
||||
{...rest}
|
||||
data-slot="button"
|
||||
type={href ? undefined : type}
|
||||
href={href && !disabled ? href : undefined}
|
||||
disabled={href ? undefined : disabled || loading}
|
||||
aria-disabled={href ? disabled : undefined}
|
||||
role={href && disabled ? 'link' : undefined}
|
||||
tabindex={href && disabled ? -1 : tabindex}
|
||||
class={cn(buttonVariants({ variant, size }), className)}
|
||||
bind:this={ref}
|
||||
onclick={async (
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
e: any
|
||||
) => {
|
||||
onclick?.(e);
|
||||
|
||||
if (type === undefined) return;
|
||||
|
||||
if (onClickPromise) {
|
||||
loading = true;
|
||||
|
||||
await onClickPromise(e);
|
||||
|
||||
loading = false;
|
||||
}
|
||||
}}
|
||||
>
|
||||
{#if type !== undefined && loading}
|
||||
<div class="ui:absolute ui:flex ui:size-full ui:place-items-center ui:justify-center ui:bg-inherit">
|
||||
<div class="ui:flex ui:animate-spin ui:place-items-center ui:justify-center">
|
||||
<LoaderCircleIcon class="ui:size-4" />
|
||||
</div>
|
||||
</div>
|
||||
<span class="ui:sr-only">Loading</span>
|
||||
{/if}
|
||||
{@render children?.()}
|
||||
</svelte:element>
|
||||
|
||||
@@ -1,17 +1,27 @@
|
||||
/*
|
||||
Installed from @ieedan/shadcn-svelte-extras
|
||||
*/
|
||||
|
||||
import Root, {
|
||||
type ButtonProps,
|
||||
type ButtonSize,
|
||||
type ButtonVariant,
|
||||
buttonVariants,
|
||||
} from "./button.svelte";
|
||||
type ButtonProps,
|
||||
type ButtonSize,
|
||||
type ButtonVariant,
|
||||
type AnchorElementProps,
|
||||
type ButtonElementProps,
|
||||
type ButtonPropsWithoutHTML,
|
||||
buttonVariants
|
||||
} from './button.svelte';
|
||||
|
||||
export {
|
||||
Root,
|
||||
type ButtonProps as Props,
|
||||
//
|
||||
Root as Button,
|
||||
buttonVariants,
|
||||
type ButtonProps,
|
||||
type ButtonSize,
|
||||
type ButtonVariant,
|
||||
Root,
|
||||
type ButtonProps as Props,
|
||||
//
|
||||
Root as Button,
|
||||
buttonVariants,
|
||||
type ButtonProps,
|
||||
type ButtonSize,
|
||||
type ButtonVariant,
|
||||
type AnchorElementProps,
|
||||
type ButtonElementProps,
|
||||
type ButtonPropsWithoutHTML
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user