spacedrive/interface/app/$libraryId/spacedrop.tsx
Brendan Allan c65d92ee4c
[ENG-380] Interface code structure improvement (#581)
* beginnings of app directory

* settings mostly good

* colocate way more components

* flatten components folder

* reexport QueryClientProvider from client

* move CodeBlock back to interface

* colocate Explorer, KeyManager + more

* goddamn captialisation

* get toasts out of components

* please eslint

* no more src directory

* $ instead of :

* added back RowHeader component

* fix settings modal padding

* more spacing, less margin

* fix sidebar locations button

* fix tags sidebar link

* clean up back button

* added margin to explorer context menu to prevent contact with edge of viewport

* don't export QueryClientProvider from @sd/client

* basic guidelines

* import interface correctly

* remove old demo data

* fix onboarding layout

* fix onboarding navigation

* fix key manager settings button

---------

Co-authored-by: Jamie Pine <ijamespine@me.com>
2023-02-27 21:29:48 -08:00

152 lines
4.7 KiB
TypeScript

import GoogleDrive from '@sd/assets/images/GoogleDrive.png';
import Mega from '@sd/assets/images/Mega.png';
import iCloud from '@sd/assets/images/iCloud.png';
import clsx from 'clsx';
import { DeviceMobile, HardDrives, Icon, Laptop, Star, User } from 'phosphor-react';
import { useRef } from 'react';
import { tw } from '@sd/ui';
import { SubtleButton, SubtleButtonContainer } from '~/components/SubtleButton';
import { OperatingSystem } from '~/util/Platform';
import { SearchBar } from './Explorer/TopBar';
import * as PageLayout from './PageLayout';
import classes from './spacedrop.module.scss';
// TODO: move this to UI, copied from Inspector
const Pill = tw.span`mt-1 inline border border-transparent px-0.5 text-[9px] font-medium shadow shadow-app-shade/5 bg-app-selected rounded text-ink-dull`;
type DropItemProps = {
// TODO: remove optionals when dummy data is removed (except for icon)
name?: string;
connectionType?: 'lan' | 'bluetooth' | 'usb' | 'p2p' | 'cloud';
receivingNodeOsType?: Omit<OperatingSystem, 'unknown'>;
} & ({ image: string } | { icon?: Icon } | { brandIcon: string });
function DropItem(props: DropItemProps) {
let icon;
if ('image' in props) {
icon = <img className="rounded-full" src={props.image} alt={props.name} />;
} else if ('brandIcon' in props) {
let brandIconSrc;
switch (props.brandIcon) {
case 'google-drive':
brandIconSrc = GoogleDrive;
break;
case 'icloud':
brandIconSrc = iCloud;
break;
case 'mega':
brandIconSrc = Mega;
break;
}
if (brandIconSrc) {
icon = (
<div className="flex h-full items-center justify-center p-3">
<img className="rounded-full " src={brandIconSrc} alt={props.name} />
</div>
);
}
} else {
//
const Icon = props.icon || User;
icon = <Icon className={clsx('m-3 h-8 w-8', !props.name && 'opacity-20')} />;
}
return (
<div
className={clsx(classes.honeycombItem, 'bg-app-box/20 hover:bg-app-box/50 overflow-hidden')}
>
<div className="group relative flex h-full w-full flex-col items-center justify-center ">
<SubtleButtonContainer className="absolute left-[12px] top-[55px]">
<SubtleButton icon={Star} />
</SubtleButtonContainer>
<div className="bg-app-button h-14 w-14 rounded-full">{icon}</div>
<SubtleButtonContainer className="absolute right-[12px] top-[55px] rotate-90">
<SubtleButton />
</SubtleButtonContainer>
{props.name && <span className="mt-1 text-xs font-medium">{props.name}</span>}
<div className="flex flex-row space-x-1">
{props.receivingNodeOsType && <Pill>{props.receivingNodeOsType}</Pill>}
{props.connectionType && (
<Pill
className={clsx(
'uppercase !text-white',
props.connectionType === 'lan' && 'bg-green-500',
props.connectionType === 'p2p' && 'bg-blue-500'
)}
>
{props.connectionType}
</Pill>
)}
</div>
</div>
</div>
);
}
export default () => {
const searchRef = useRef<HTMLInputElement>(null);
return (
<>
<PageLayout.DragChildren>
<div className="flex h-8 w-full flex-row items-center justify-center pt-3">
<SearchBar className="ml-[13px]" ref={searchRef} />
{/* <Button variant="outline">Add</Button> */}
</div>
</PageLayout.DragChildren>
<div className={classes.honeycombOuter}>
<div className={clsx(classes.honeycombContainer, 'mt-8')}>
<DropItem
name="Jamie's MacBook Pro"
receivingNodeOsType="macOS"
connectionType="lan"
icon={Laptop}
/>
<DropItem
name="Jamie's iPhone"
receivingNodeOsType="iOS"
connectionType="lan"
icon={DeviceMobile}
/>
<DropItem
name="Titan NAS"
receivingNodeOsType="linux"
connectionType="p2p"
icon={HardDrives}
/>
<DropItem
name="Jamie's iPad"
receivingNodeOsType="iOS"
connectionType="lan"
icon={DeviceMobile}
/>
<DropItem name="Jamie's Google Drive" brandIcon="google-drive" connectionType="cloud" />
<DropItem name="Jamie's iCloud" brandIcon="icloud" connectionType="cloud" />
<DropItem name="Mega" brandIcon="mega" connectionType="cloud" />
<DropItem
name="maxichrome"
image="https://github.com/maxichrome.png"
connectionType="p2p"
/>
<DropItem
name="Brendan Alan"
image="https://github.com/brendonovich.png"
connectionType="p2p"
/>
<DropItem
name="Oscar Beaumont"
image="https://github.com/oscartbeaumont.png"
connectionType="p2p"
/>
<DropItem name="Polar" image="https://github.com/polargh.png" connectionType="p2p" />
<DropItem
name="Andrew Haskell"
image="https://github.com/andrewtechx.png"
connectionType="p2p"
/>
</div>
</div>
</>
);
};