feat: team draft

This commit is contained in:
2024-11-12 19:15:13 +07:00
parent 8159b65605
commit f5250d5361
23 changed files with 313 additions and 48 deletions
+9 -11
View File
@@ -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;
+4
View File
@@ -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;
+50
View File
@@ -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;