mirror of
https://github.com/khairul169/vaulterm.git
synced 2026-09-15 17:03:30 +07:00
feat: team draft
This commit is contained in:
@@ -10,27 +10,25 @@ import {
|
||||
useLinkBuilder,
|
||||
} from "@react-navigation/native";
|
||||
import { Link } from "expo-router";
|
||||
import Icons from "../ui/icons";
|
||||
import { logout } from "@/stores/auth";
|
||||
import ThemeSwitcher from "./theme-switcher";
|
||||
import UserMenuButton from "./user-menu-button";
|
||||
|
||||
const Drawer = (props: DrawerContentComponentProps) => {
|
||||
return (
|
||||
<>
|
||||
<View p="$4">
|
||||
<UserMenuButton />
|
||||
</View>
|
||||
|
||||
<DrawerContentScrollView
|
||||
contentContainerStyle={{ padding: 18 }}
|
||||
contentContainerStyle={{ padding: 18, paddingTop: 0 }}
|
||||
{...props}
|
||||
>
|
||||
<DrawerItemList {...props} />
|
||||
</DrawerContentScrollView>
|
||||
|
||||
<View p="$4">
|
||||
<Button
|
||||
justifyContent="flex-start"
|
||||
icon={<Icons name="logout" size={16} />}
|
||||
onPress={() => logout()}
|
||||
>
|
||||
Logout
|
||||
</Button>
|
||||
<View px="$4" py="$2">
|
||||
<ThemeSwitcher />
|
||||
</View>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -1,28 +1,36 @@
|
||||
import React from "react";
|
||||
import { Button, GetProps } from "tamagui";
|
||||
import Icons from "../ui/icons";
|
||||
import React, { useId } from "react";
|
||||
import { Switch, GetProps, XStack, Label } from "tamagui";
|
||||
import useThemeStore from "@/stores/theme";
|
||||
import { Ionicons } from "../ui/icons";
|
||||
|
||||
type Props = GetProps<typeof Button> & {
|
||||
type Props = GetProps<typeof XStack> & {
|
||||
iconSize?: number;
|
||||
};
|
||||
|
||||
const ThemeSwitcher = ({ iconSize = 24, ...props }: Props) => {
|
||||
const ThemeSwitcher = ({ iconSize = 18, ...props }: Props) => {
|
||||
const { theme, toggle } = useThemeStore();
|
||||
const id = useId();
|
||||
|
||||
return (
|
||||
<Button
|
||||
icon={
|
||||
<Icons
|
||||
name={
|
||||
theme === "light" ? "white-balance-sunny" : "moon-waning-crescent"
|
||||
}
|
||||
size={iconSize}
|
||||
/>
|
||||
}
|
||||
onPress={toggle}
|
||||
{...props}
|
||||
/>
|
||||
<XStack alignItems="center" gap="$2">
|
||||
<Ionicons
|
||||
name={theme === "light" ? "moon-outline" : "sunny-outline"}
|
||||
size={iconSize}
|
||||
/>
|
||||
<Label htmlFor={id} flex={1} cursor="pointer">
|
||||
{`${theme === "light" ? "Dark" : "Light"} Mode`}
|
||||
</Label>
|
||||
<Switch
|
||||
id={id}
|
||||
onPress={toggle}
|
||||
checked={theme === "dark"}
|
||||
size="$2"
|
||||
cursor="pointer"
|
||||
{...props}
|
||||
>
|
||||
<Switch.Thumb animation="quicker" />
|
||||
</Switch>
|
||||
</XStack>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
import React from "react";
|
||||
import {
|
||||
Avatar,
|
||||
Button,
|
||||
ListItem,
|
||||
Separator,
|
||||
Text,
|
||||
useMedia,
|
||||
View,
|
||||
YGroup,
|
||||
} from "tamagui";
|
||||
import MenuButton from "../ui/menu-button";
|
||||
import Icons from "../ui/icons";
|
||||
import { logout } from "@/stores/auth";
|
||||
import { useUser } from "@/hooks/useUser";
|
||||
|
||||
const UserMenuButton = () => {
|
||||
const user = useUser();
|
||||
|
||||
return (
|
||||
<MenuButton
|
||||
size="$1"
|
||||
placement="bottom-end"
|
||||
width={213}
|
||||
trigger={
|
||||
<Button
|
||||
bg="$colorTransparent"
|
||||
justifyContent="flex-start"
|
||||
p={0}
|
||||
gap="$1"
|
||||
>
|
||||
<Avatar circular size="$3">
|
||||
<Avatar.Fallback bg="$blue4" />
|
||||
</Avatar>
|
||||
<View flex={1} style={{ textAlign: "left" }}>
|
||||
<Text numberOfLines={1}>{user?.name}</Text>
|
||||
<Text numberOfLines={1} fontWeight="600" mt="$1.5">
|
||||
Personal
|
||||
</Text>
|
||||
</View>
|
||||
<Icons name="chevron-down" size={16} />
|
||||
</Button>
|
||||
}
|
||||
>
|
||||
<TeamsMenu />
|
||||
<MenuButton.Item
|
||||
onPress={() => console.log("logout")}
|
||||
icon={<Icons name="account" size={16} />}
|
||||
title="Account"
|
||||
/>
|
||||
<Separator w="100%" />
|
||||
<MenuButton.Item
|
||||
onPress={() => logout()}
|
||||
icon={<Icons name="logout" size={16} />}
|
||||
title="Logout"
|
||||
/>
|
||||
</MenuButton>
|
||||
);
|
||||
};
|
||||
|
||||
const TeamsMenu = () => {
|
||||
const media = useMedia();
|
||||
const user = useUser();
|
||||
const teams = user?.teams || [];
|
||||
|
||||
return (
|
||||
<MenuButton
|
||||
size="$1"
|
||||
placement={media.xs ? "bottom" : "right-start"}
|
||||
asChild
|
||||
width={213}
|
||||
trigger={
|
||||
<ListItem
|
||||
hoverTheme
|
||||
pressTheme
|
||||
onPress={() => console.log("logout")}
|
||||
icon={<Icons name="account-group" size={16} />}
|
||||
title="Teams"
|
||||
iconAfter={<Icons name="chevron-right" size={16} />}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<MenuButton.Item
|
||||
icon={<Icons name="account" size={16} />}
|
||||
title="Personal"
|
||||
/>
|
||||
|
||||
{teams.map((team: any) => (
|
||||
<MenuButton.Item icon={<Text>{team.icon}</Text>} title={team.name} />
|
||||
))}
|
||||
|
||||
{teams.length > 0 && <Separator width="100%" />}
|
||||
|
||||
<MenuButton.Item
|
||||
icon={<Icons name="plus" size={16} />}
|
||||
title="Create Team"
|
||||
/>
|
||||
</MenuButton>
|
||||
);
|
||||
};
|
||||
|
||||
export default UserMenuButton;
|
||||
@@ -1,8 +1,12 @@
|
||||
import MaterialCommunityIcons from "@expo/vector-icons/MaterialCommunityIcons";
|
||||
import IoniconsIcon from "@expo/vector-icons/Ionicons";
|
||||
import { styled } from "tamagui";
|
||||
|
||||
export const Icons = styled(MaterialCommunityIcons, {
|
||||
color: "$color",
|
||||
});
|
||||
export const Ionicons = styled(IoniconsIcon, {
|
||||
color: "$color",
|
||||
});
|
||||
|
||||
export default Icons;
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
import React from "react";
|
||||
import {
|
||||
GetProps,
|
||||
ListItem,
|
||||
Popover,
|
||||
styled,
|
||||
withStaticProperties,
|
||||
} from "tamagui";
|
||||
|
||||
type MenuButtonProps = GetProps<typeof Popover> & {
|
||||
asChild?: boolean;
|
||||
trigger?: React.ReactNode;
|
||||
width?: string | number | null;
|
||||
};
|
||||
|
||||
const MenuButtonFrame = ({
|
||||
asChild,
|
||||
trigger,
|
||||
children,
|
||||
width,
|
||||
...props
|
||||
}: MenuButtonProps) => {
|
||||
return (
|
||||
<Popover {...props}>
|
||||
<Popover.Trigger asChild={asChild}>{trigger}</Popover.Trigger>
|
||||
|
||||
<Popover.Content
|
||||
bordered
|
||||
enterStyle={{ y: -10, opacity: 0 }}
|
||||
exitStyle={{ y: -10, opacity: 0 }}
|
||||
animation={["quick", { opacity: { overshootClamping: true } }]}
|
||||
width={width}
|
||||
>
|
||||
{children}
|
||||
</Popover.Content>
|
||||
</Popover>
|
||||
);
|
||||
};
|
||||
|
||||
const MenuButtonItem = (props: GetProps<typeof ListItem>) => (
|
||||
<Popover.Close asChild>
|
||||
<ListItem hoverTheme pressTheme {...props} />
|
||||
</Popover.Close>
|
||||
);
|
||||
|
||||
const MenuButton = withStaticProperties(MenuButtonFrame, {
|
||||
Item: MenuButtonItem,
|
||||
});
|
||||
|
||||
export default MenuButton;
|
||||
Reference in New Issue
Block a user