finish sidebar, some fixes

This commit is contained in:
Stef-00012 2025-01-27 16:02:42 +01:00
parent 3c0909c1ab
commit fdb827a1f1
No known key found for this signature in database
GPG key ID: 28BE9A9E4EF0E6BF
18 changed files with 507 additions and 135 deletions

View file

@ -6,7 +6,7 @@ import { View, Text, Pressable, Image } from "react-native";
import type { APISelfUser } from "@/types/zipline";
import { styles } from "@/styles/components/header";
import type React from "react";
import Sidebar from "@/components/Sidebar.tsx"
import Sidebar from "@/components/Sidebar"
export default function Header({ children }: PropsWithChildren) {
const [avatar, setAvatar] = useState<string | null>(null);

View file

@ -14,8 +14,6 @@ interface Props {
export default function LargeFileDisplay({ file, hidden, onClose }: Props) {
const dashUrl = db.get("url") as DashURL | null;
console.log("aagdrgf")
return (
<Pressable
style={{

View file

@ -1,10 +1,10 @@
import React, { useEffect, useRef, useState } from "react";
import { Animated, StyleSheet, View, Dimensions, Text, Pressable } from "react-native";
import React, { type Dispatch, type SetStateAction, useEffect, useRef, useState } from "react";
import { Animated, View, Dimensions, Text, Pressable } from "react-native";
import { styles } from "@/styles/components/sidebar";
import { usePathname } from "expo-router"
import { type RelativePathString, usePathname } from "expo-router"
import { getSettings } from "@/functions/zipline/settings";
import { getCurrentUser } from "@/functions/zipline/user";
import { sidebarOptions } from "@/constants/sidebar"
import { type SidebarOption, sidebarOptions } from "@/constants/sidebar"
import MaterialIcons from "@expo/vector-icons/MaterialIcons";
import { useRouter } from "expo-router"
@ -16,6 +16,8 @@ interface Props {
export default function Sidebar({ open = false, paddingTop = 0, setOpen }: Props) {
const router = useRouter()
const [openStates, setOpenStates] = useState<Record<string, boolean>>({})
const screenWidth = Dimensions.get("window").width;
const translateX = useRef(new Animated.Value(-screenWidth)).current;
@ -28,13 +30,14 @@ export default function Sidebar({ open = false, paddingTop = 0, setOpen }: Props
const settings = await getSettings()
const user = await getCurrentUser()
if (user && ["ADMIN", "SUPERADMIN"].includes(user.role)) setIsAdmin(true)
if (settings && settings.invitesEnabled) setInvitesEnabled(true)
if (typeof user !== "string" && ["ADMIN", "SUPERADMIN"].includes(user.role)) setIsAdmin(true)
if (typeof settings !== "string" && settings.invitesEnabled) setInvitesEnabled(true)
})()
})
const pathname = usePathname()
// biome-ignore lint/correctness/useExhaustiveDependencies:.
useEffect(() => {
Animated.timing(translateX, {
toValue: open ? 0 : -screenWidth,
@ -44,29 +47,77 @@ export default function Sidebar({ open = false, paddingTop = 0, setOpen }: Props
}, [open, screenWidth]);
return (
<Animated.View style={[styles.sidebar, { transform: [{ translateX }], width: screenWidth, paddingTop }]}>
{/* Your sidebar content goes here */}
<View style={styles.sidebarContent}>
{sidebarOptions.map((option) => {
const isActive = pathname === option.route;
if (option.type === "button") return (
<Pressable key={option.route} onPress={() => {
setOpen(false)
router.replace(option.route)
}} href={option.route} style={{
...styles.sidebarOption,
...(isActive && styles.sidebarOptionActive)
}}>
<MaterialIcons name={option.icon} size={20} color={isActive ? styles.sidebarOptionTextActive.color : styles.sidebarOptionText.color} />
<Text style={{
...styles.sidebarOptionText,
...(isActive && styles.sidebarOptionTextActive)
}}>{option.name}</Text>
</Pressable>
)
})}
<Animated.View style={[
styles.sidebar,
{
transform: [{
translateX
}],
width: screenWidth,
paddingTop
}]}>
<View>
{sidebarOptions.map(renderSidebarOptions)}
</View>
</Animated.View>
);
function renderSidebarOptions(option: SidebarOption) {
if (option.adminOnly && !isAdmin) return (
<View key={option.route || option.name} />
)
if (option.invitesRoute && !invitesEnabled) return (
<View key={option.route || option.name} />
)
if (option.type === "button") {
const isActive = pathname === option.route;
const route = option.route as RelativePathString
return (
<Pressable key={route} onPress={() => {
setOpen(false)
if (isActive) return;
router.replace(route)
}} style={{
...styles.sidebarOption,
...(isActive && styles.sidebarOptionActive)
}}>
<MaterialIcons name={option.icon} size={20} color={isActive ? styles.sidebarOptionTextActive.color : styles.sidebarOptionText.color} />
<Text style={{
...styles.sidebarOptionText,
...(isActive && styles.sidebarOptionTextActive)
}}>{option.name}</Text>
</Pressable>
)
}
if (option.type === "select") {
const open = openStates[option.name] ?? false
return (
<View key={option.name}>
<Pressable onPress={() => setOpenStates((prev) => {
return {
...prev,
[option.name]: !prev[option.name]
}
})} style={styles.sidebarOption}>
<MaterialIcons name={option.icon} size={20} color={styles.sidebarOptionText.color} />
<Text style={styles.sidebarOptionText}>{option.name}</Text>
<MaterialIcons name={open ? "expand-more" : "expand-less"} size={20} color={styles.sidebarOptionText.color} />
</Pressable>
{open && (
<View style={{ paddingLeft: 20 }}>
{option.subMenus.map(renderSidebarOptions)}
</View>
)}
</View>
);
}
}
}

0
components/tmp.tsx Normal file
View file