mirror of
https://github.com/Viren070/AIOStreams.git
synced 2025-12-01 23:14:04 +01:00
feat: add alert and socials options to schema, implement SocialIcon component, and update TemplateOption to render new option types
This commit is contained in:
@@ -176,6 +176,8 @@ const OptionDefinition = z.object({
|
||||
'select',
|
||||
'multi-select',
|
||||
'url',
|
||||
'alert',
|
||||
'socials',
|
||||
]),
|
||||
required: z.boolean().optional(),
|
||||
default: z.any().optional(),
|
||||
@@ -189,6 +191,34 @@ const OptionDefinition = z.object({
|
||||
})
|
||||
)
|
||||
.optional(),
|
||||
intent: z
|
||||
.enum([
|
||||
'alert',
|
||||
'info',
|
||||
'success',
|
||||
'warning',
|
||||
'info-basic',
|
||||
'success-basic',
|
||||
'warning-basic',
|
||||
'alert-basic',
|
||||
])
|
||||
.optional(),
|
||||
socials: z
|
||||
.array(
|
||||
z.object({
|
||||
id: z.enum([
|
||||
'website',
|
||||
'github',
|
||||
'discord',
|
||||
'ko-fi',
|
||||
'patreon',
|
||||
'buymeacoffee',
|
||||
'github-sponsors',
|
||||
]),
|
||||
url: z.string().url(),
|
||||
})
|
||||
)
|
||||
.optional(),
|
||||
constraints: z
|
||||
.object({
|
||||
min: z.number().min(1).optional(), // for string inputs, consider this the minimum length.
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
import { cn } from '@/components/ui/core/styling';
|
||||
import { FiGithub } from 'react-icons/fi';
|
||||
import { AiOutlineDiscord } from 'react-icons/ai';
|
||||
import { FaPatreon } from 'react-icons/fa6';
|
||||
import { SiBuymeacoffee, SiGithubsponsors, SiKofi } from 'react-icons/si';
|
||||
import { Tooltip } from '../ui/tooltip';
|
||||
import { FaGlobe } from 'react-icons/fa6';
|
||||
|
||||
type SocialIconProps = {
|
||||
id:
|
||||
| 'github'
|
||||
| 'discord'
|
||||
| 'ko-fi'
|
||||
| 'patreon'
|
||||
| 'buymeacoffee'
|
||||
| 'github-sponsors'
|
||||
| 'website';
|
||||
url: string;
|
||||
className?: string;
|
||||
};
|
||||
|
||||
export function SocialIcon({ id, url, className }: SocialIconProps) {
|
||||
const getTooltip = () => {
|
||||
switch (id) {
|
||||
case 'github':
|
||||
return "View the addon's GitHub repository";
|
||||
case 'discord':
|
||||
return "Join the Developer's Discord";
|
||||
case 'github-sponsors':
|
||||
return 'Sponsor the Developer on GitHub';
|
||||
case 'ko-fi':
|
||||
return 'Support the Developer on Ko-fi';
|
||||
case 'patreon':
|
||||
return 'Support the Developer on Patreon';
|
||||
case 'buymeacoffee':
|
||||
return 'Support the Developer on Buy Me a Coffee';
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const tooltip = getTooltip();
|
||||
|
||||
return tooltip ? (
|
||||
<Tooltip
|
||||
side="top"
|
||||
trigger={<SocialIconComponent id={id} url={url} className={className} />}
|
||||
>
|
||||
{tooltip}
|
||||
</Tooltip>
|
||||
) : (
|
||||
<SocialIconComponent id={id} url={url} className={className} />
|
||||
);
|
||||
}
|
||||
|
||||
const SocialIconComponent = ({ id, url, className }: SocialIconProps) => {
|
||||
const getIcon = () => {
|
||||
switch (id) {
|
||||
case 'website':
|
||||
return <FaGlobe className="w-7 h-7" />;
|
||||
case 'discord':
|
||||
return <AiOutlineDiscord className="w-7 h-7" />;
|
||||
case 'github':
|
||||
return <FiGithub className="w-7 h-7" />;
|
||||
case 'github-sponsors':
|
||||
return <SiGithubsponsors className="w-7 h-7" />;
|
||||
case 'ko-fi':
|
||||
return <SiKofi className="w-7 h-7" />;
|
||||
case 'patreon':
|
||||
return <FaPatreon className="w-7 h-7" />;
|
||||
case 'buymeacoffee':
|
||||
return <SiBuymeacoffee className="w-7 h-7" />;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
return (
|
||||
<a
|
||||
href={url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className={cn(
|
||||
'inline-flex items-center justify-center text-gray-400 transition-colors hover:opacity-80 hover:text-[--brand]',
|
||||
className
|
||||
)}
|
||||
>
|
||||
{getIcon()}
|
||||
</a>
|
||||
);
|
||||
};
|
||||
@@ -6,6 +6,8 @@ import { Combobox } from '../ui/combobox';
|
||||
import { Option } from '@aiostreams/core';
|
||||
import React from 'react';
|
||||
import MarkdownLite from './markdown-lite';
|
||||
import { Alert } from '../ui/alert';
|
||||
import { SocialIcon } from './social-icon';
|
||||
// this component, accepts an option and returns a component that renders the option.
|
||||
// string - TextInput
|
||||
// number - NumberInput
|
||||
@@ -38,12 +40,30 @@ const TemplateOption: React.FC<TemplateOptionProps> = ({
|
||||
constraints,
|
||||
forced,
|
||||
default: defaultValue,
|
||||
intent,
|
||||
socials,
|
||||
emptyIsUndefined = false,
|
||||
} = option;
|
||||
|
||||
const isDisabled = disabled || !!forced;
|
||||
|
||||
switch (type) {
|
||||
case 'socials':
|
||||
return (
|
||||
<div className="flex items-center justify-center w-full gap-6 mt-2">
|
||||
{socials?.map((social) => (
|
||||
<SocialIcon key={social.id} id={social.id} url={social.url} />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
case 'alert':
|
||||
return (
|
||||
<Alert
|
||||
intent={intent}
|
||||
title={name}
|
||||
description={<MarkdownLite>{description}</MarkdownLite>}
|
||||
/>
|
||||
);
|
||||
case 'password':
|
||||
return (
|
||||
<div>
|
||||
|
||||
Reference in New Issue
Block a user