Skip to content

Commit

Permalink
Small updates; Added Favicon option to the theme;
Browse files Browse the repository at this point in the history
  • Loading branch information
stef-coenen committed Sep 8, 2023
1 parent 28fa94e commit 2307bd2
Show file tree
Hide file tree
Showing 11 changed files with 323 additions and 138 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { createPortal } from 'react-dom';
import { usePortal, DialogWrapper, Times } from '@youfoundation/common-app';
import { usePortal, Times } from '@youfoundation/common-app';
import { EmbeddedThumb, TargetDrive } from '@youfoundation/js-lib/core';
import { Image } from '@youfoundation/common-app';
import { useEffect } from 'react';
Expand Down Expand Up @@ -44,7 +44,7 @@ export const ImageLightbox = ({
<div className="fixed inset-0 z-50 bg-black lg:bg-transparent" role="dialog" aria-modal="true">
<div className="inset-0 bg-black transition-opacity lg:fixed"></div>
<div className="inset-0 z-10 lg:fixed lg:overflow-y-auto">
<div className="relative flex h-full min-h-screen flex-col lg:flex-row">
<div className="relative flex h-full min-h-screen flex-col lg:flex-row" onClick={onClose}>
{onClose ? (
<button
onClick={onClose}
Expand All @@ -53,6 +53,7 @@ export const ImageLightbox = ({
<Times className="h-4 w-4" />
</button>
) : null}

<Image
className={`m-auto h-auto max-h-[calc(100vh-5rem)] w-auto max-w-full object-contain`}
fileId={fileId}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,7 @@ export const ImageCropper = ({ imageUrl, expectedAspectRatio, onChange }: ImageC
const cropper = imageElement?.cropper;

cropper?.getCroppedCanvas().toBlob((blob) => {
if (!blob) {
return;
}
if (!blob) return;

new Blob([blob], { type: OUTPUT_MIME_TYPE }).arrayBuffer().then((buffer) => {
const contentByteArray = new Uint8Array(buffer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ export const CommentEditor = ({
/>
<div className="flex flex-shrink-0 flex-row items-center ">
<EmojiSelector
size="small"
className="text-opacity-30 hover:text-opacity-100"
onInput={(val) => setBody((oldVal) => `${oldVal} ${val}`)}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,35 +8,45 @@ const EmojiPicker = lazy(() =>
export const EmojiSelector = ({
className,
onInput,
defaultValue,
size,
}: {
className?: string;
onInput: (val: string) => void;
defaultValue?: string;
size?: 'large' | 'small' | 'square' | 'none';
}) => {
const [isOpen, setIsOpen] = useState(false);

const wrapperRef = useRef<HTMLDivElement>(null);
useOutsideTrigger(wrapperRef, () => setIsOpen(false));
const { verticalSpace } = useMostSpace(wrapperRef);
const { verticalSpace, horizontalSpace } = useMostSpace(wrapperRef);

return (
<div className={`relative ${className ?? ''}`}>
<ActionButton
type="mute"
size="small"
className={`text-foreground text-opacity-30 hover:text-opacity-100`}
size={size}
className={`text-foreground ${
defaultValue ? 'text-opacity-70' : 'text-opacity-30'
} hover:text-opacity-100`}
onClick={() => setIsOpen(!isOpen)}
icon={Lol}
icon={defaultValue ? undefined : Lol}
children={defaultValue || null}
/>
<div
className={`absolute ${
verticalSpace === 'top' ? 'bottom-[100%]' : 'top-[100%]'
} right-[-2.7rem] z-20 sm:right-0`}
className={`absolute ${verticalSpace === 'top' ? 'bottom-[100%]' : 'top-[100%]'} ${
horizontalSpace === 'left' ? 'right-[-2.7rem] sm:right-0' : 'left-[-2.7rem] sm:left-0'
} z-20 `}
ref={wrapperRef}
>
{isOpen ? (
<Suspense>
<EmojiPicker
onInput={(emojiDetail) => onInput(emojiDetail.unicode)}
onInput={(emojiDetail) => {
onInput(emojiDetail.unicode);
setIsOpen(false);
}}
key={'emoji-picker'}
/>
</Suspense>
Expand Down
4 changes: 4 additions & 0 deletions packages/js-lib/src/public/home/HomeTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,9 @@ export class HomePageFields {

export class HomePageThemeFields {
static readonly ThemeId: string = 'themeId';
static readonly Favicon: string = 'favicon';
static readonly Colors: string = 'colors';
static readonly Tabs: string = 'tabs';
static readonly TabsOrder: string = 'tabsOrder';
static readonly UseDarkMode: string = 'useDarkMode';
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
HomePageConfig,
HomePageFields,
HomePageTheme,
HomePageThemeFields,
} from '@youfoundation/js-lib/public';
import {
BirthdayFields,
Expand Down Expand Up @@ -32,6 +33,7 @@ import ThemeSelector from '../../Form/ThemeSelector';
import ImageSelector from '@youfoundation/common-app/src/form/image/ImageSelector';
import { ThumbnailInstruction } from '@youfoundation/js-lib/core';
import { generateDisplayLocation, generateDisplayName } from '@youfoundation/js-lib/helpers';
import FaviconSelector from '../../Form/FaviconSelector';

const profileInstructionThumbSizes: ThumbnailInstruction[] = [
{ quality: 85, width: 250, height: 250 },
Expand All @@ -53,9 +55,6 @@ const AttributeFields = ({
}) => {
const debouncedChange = useMemo(() => debounce(onChange, 500), [onChange]);

// Home consts:
const DEFAULT_TABS_ORDER = ['Posts', 'Links', 'About', 'Connections'];

switch (attribute.type) {
case BuiltInAttributes.Name:
return <NameAttributeEditor attribute={attribute} onChange={debouncedChange} />;
Expand Down Expand Up @@ -301,102 +300,10 @@ const AttributeFields = ({
);
break;
case HomePageAttributes.HomePage:
return (
<>
<div className="mb-5">
<Label htmlFor="headerImage">{t('Background photo')}</Label>
<ImageSelector
id="headerImage"
name={HomePageFields.HeaderImageId}
defaultValue={attribute.data?.[HomePageFields.HeaderImageId] ?? ''}
onChange={(e) =>
onChange({ target: { name: e.target.name, value: e.target.value?.fileId } })
}
acl={attribute.acl}
targetDrive={GetTargetDriveFromProfileId(HomePageConfig.DefaultDriveId)}
sizeClass={`${
!attribute.data?.[HomePageFields.HeaderImageId]
? 'aspect-[16/9] md:aspect-[5/1]'
: ''
} w-full object-cover`}
thumbInstructions={headerInstructionThumbSizes}
/>
</div>
<div className="mb-5">
<Label htmlFor="tagLine">{t('Headline')}</Label>
<Input
id="tagLine"
name="tagLine"
defaultValue={attribute.data?.['tagLine'] ?? ''}
onChange={debouncedChange}
/>
</div>
<div className="mb-5">
<Label htmlFor="leadText">{t('About')}</Label>
<Textarea
id="leadText"
name="leadText"
defaultValue={attribute.data?.['leadText'] ?? ''}
onChange={debouncedChange}
/>
</div>
</>
);
return <HomeAttributeEditor attribute={attribute} onChange={debouncedChange} />;
break;
case HomePageAttributes.Theme:
return (
<>
<div className="mb-5">
<Label htmlFor="themeId">{t('Theme')}</Label>
<ThemeSelector
name="themeId"
defaultValue={attribute.data?.['themeId'] ?? ''}
onChange={debouncedChange}
/>
</div>
<div className="mb-5">
<Label htmlFor="colors">{t('Color set')}</Label>
<ColorThemeSelector
id="colors"
name="colors"
defaultValue={attribute.data?.['colors'] ?? ''}
onChange={debouncedChange}
/>
</div>
{(attribute.data?.['themeId'] === HomePageTheme.SocialClassic.toString() ||
attribute.data?.['themeId'] === HomePageTheme.ContentProducer.toString()) && (
<>
<div className="mb-5">
<Label htmlFor="tabs">{t('Show tabs')}</Label>
<Select
id="tabs"
name="tabs"
defaultValue={attribute.data?.['tabs'] ?? ''}
onChange={debouncedChange}
>
<option>{t('No')}</option>
<option value={'true'}>{t('Yes')}</option>
</Select>
</div>
{attribute.data?.['tabs'] === 'true' && (
<div className="mb-5">
<Label htmlFor="tabs-order">{t('Tabs Order')}</Label>
<Order
elements={
(attribute.data?.['tabsOrder'] &&
attribute.data?.['tabsOrder'].length === DEFAULT_TABS_ORDER.length &&
attribute.data['tabsOrder']) ??
DEFAULT_TABS_ORDER
}
name="tabsOrder"
onChange={debouncedChange}
/>
</div>
)}
</>
)}
</>
);
return <ThemeAttributeEditor attribute={attribute} onChange={debouncedChange} />;
break;
default:
return (
Expand Down Expand Up @@ -625,4 +532,129 @@ const PhoneAttributeEditor = ({
);
};

const HomeAttributeEditor = ({
attribute,
onChange,
}: {
attribute: AttributeVm;
onChange: (e: { target: { value: unknown; name: string } }) => void;
}) => {
return (
<>
<div className="mb-5">
<Label htmlFor="headerImage">{t('Background photo')}</Label>
<ImageSelector
id="headerImage"
name={HomePageFields.HeaderImageId}
defaultValue={attribute.data?.[HomePageFields.HeaderImageId] ?? ''}
onChange={(e) =>
onChange({ target: { name: e.target.name, value: e.target.value?.fileId } })
}
acl={attribute.acl}
targetDrive={GetTargetDriveFromProfileId(HomePageConfig.DefaultDriveId)}
sizeClass={`${
!attribute.data?.[HomePageFields.HeaderImageId] ? 'aspect-[16/9] md:aspect-[5/1]' : ''
} w-full object-cover`}
thumbInstructions={headerInstructionThumbSizes}
/>
</div>
<div className="mb-5">
<Label htmlFor="tagLine">{t('Headline')}</Label>
<Input
id="tagLine"
name="tagLine"
defaultValue={attribute.data?.['tagLine'] ?? ''}
onChange={onChange}
/>
</div>
<div className="mb-5">
<Label htmlFor="leadText">{t('About')}</Label>
<Textarea
id="leadText"
name="leadText"
defaultValue={attribute.data?.['leadText'] ?? ''}
onChange={onChange}
/>
</div>
</>
);
};

const ThemeAttributeEditor = ({
attribute,
onChange,
}: {
attribute: AttributeVm;
onChange: (e: { target: { value: unknown; name: string } }) => void;
}) => {
// Home consts:
const DEFAULT_TABS_ORDER = ['Posts', 'Links', 'About', 'Connections'];

return (
<>
<div className="mb-5">
<Label htmlFor={HomePageThemeFields.ThemeId}>{t('Theme')}</Label>
<ThemeSelector
name={HomePageThemeFields.ThemeId}
defaultValue={attribute.data?.[HomePageThemeFields.ThemeId] ?? ''}
onChange={onChange}
/>
</div>
<div className="mb-5">
<Label htmlFor={HomePageThemeFields.Colors}>{t('Color set')}</Label>
<ColorThemeSelector
id={HomePageThemeFields.Colors}
name={HomePageThemeFields.Colors}
defaultValue={attribute.data?.[HomePageThemeFields.Colors] ?? ''}
onChange={onChange}
/>
</div>
{(attribute.data?.[HomePageThemeFields.ThemeId] === HomePageTheme.SocialClassic.toString() ||
attribute.data?.[HomePageThemeFields.ThemeId] ===
HomePageTheme.ContentProducer.toString()) && (
<>
<div className="mb-5">
<Label htmlFor="tabs">{t('Show tabs')}</Label>
<Select
id="tabs"
name={HomePageThemeFields.Tabs}
defaultValue={attribute.data?.[HomePageThemeFields.Tabs] ?? ''}
onChange={onChange}
>
<option>{t('No')}</option>
<option value={'true'}>{t('Yes')}</option>
</Select>
</div>
{attribute.data?.[HomePageThemeFields.Tabs] === 'true' && (
<div className="mb-5">
<Label htmlFor={HomePageThemeFields.TabsOrder}>{t('Tabs Order')}</Label>
<Order
elements={
(attribute.data?.[HomePageThemeFields.TabsOrder] &&
attribute.data?.[HomePageThemeFields.TabsOrder].length ===
DEFAULT_TABS_ORDER.length &&
attribute.data[HomePageThemeFields.TabsOrder]) ??
DEFAULT_TABS_ORDER
}
name={HomePageThemeFields.TabsOrder}
onChange={onChange}
/>
</div>
)}
</>
)}
<div className="mb-5">
<Label htmlFor={HomePageThemeFields.Favicon}>{t('Favicon')}</Label>
<FaviconSelector
name={HomePageThemeFields.Favicon}
defaultValue={attribute.data?.[HomePageThemeFields.Favicon] ?? ''}
acl={attribute.acl}
onChange={(e) => onChange({ target: { name: e.target.name, value: e.target.value } })}
targetDrive={GetTargetDriveFromProfileId(HomePageConfig.DefaultDriveId)}
/>
</div>
</>
);
};

export default AttributeFields;
Loading

0 comments on commit 2307bd2

Please sign in to comment.