Merge pull request #62 from utopia-os/typescript-navbar

fix(other): make NavBar typesafe
This commit is contained in:
antontranelis 2025-01-07 13:06:18 +00:00 committed by GitHub
commit 46ba73fd1b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 24 additions and 39 deletions

View File

@ -1,14 +1,3 @@
/* eslint-disable @typescript-eslint/no-empty-function */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/no-unsafe-argument */
/* eslint-disable @typescript-eslint/restrict-template-expressions */
/* eslint-disable @typescript-eslint/no-floating-promises */
/* eslint-disable @typescript-eslint/no-unsafe-return */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unsafe-call */
/* eslint-disable @typescript-eslint/restrict-plus-operands */
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
import QuestionMarkIcon from '@heroicons/react/24/outline/QuestionMarkCircleIcon' import QuestionMarkIcon from '@heroicons/react/24/outline/QuestionMarkCircleIcon'
import { useEffect, useRef, useState } from 'react' import { useEffect, useRef, useState } from 'react'
import { Link, useLocation } from 'react-router-dom' import { Link, useLocation } from 'react-router-dom'
@ -31,19 +20,19 @@ export default function NavBar({ appName, userType }: { appName: string; userTyp
items.find((i) => i.user_created?.id === user.id && i.layer?.itemType.name === userType) items.find((i) => i.user_created?.id === user.id && i.layer?.itemType.name === userType)
profile profile
? setUserProfile(profile) ? setUserProfile(profile)
: setUserProfile({ id: crypto.randomUUID(), name: user?.first_name, text: '' }) : setUserProfile({ id: crypto.randomUUID(), name: user?.first_name ?? '', text: '' })
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [user, items]) }, [user, items])
useEffect(() => {}, [userProfile]) // useEffect(() => {}, [userProfile])
const nameRef = useRef<any>(null) const nameRef = useRef<HTMLHeadingElement>(null)
const [nameWidth, setNameWidth] = useState<number>(0) const [nameWidth, setNameWidth] = useState<number>(0)
const location = useLocation() const location = useLocation()
const [showNav, setShowNav] = useState<boolean>(false) const [showNav, setShowNav] = useState<boolean>(false)
useEffect(() => { useEffect(() => {
showNav && nameRef && setNameWidth(nameRef.current.scrollWidth) showNav && nameRef.current && setNameWidth(nameRef.current.scrollWidth)
}, [nameRef, appName, showNav]) }, [nameRef, appName, showNav])
useEffect(() => { useEffect(() => {
@ -52,8 +41,8 @@ export default function NavBar({ appName, userType }: { appName: string; userTyp
embedded !== 'true' && setShowNav(true) embedded !== 'true' && setShowNav(true)
}, [location]) }, [location])
const onLogout = () => { const onLogout = async () => {
toast.promise(logout(), { await toast.promise(logout(), {
success: { success: {
render() { render() {
return 'Bye bye' return 'Bye bye'
@ -63,7 +52,7 @@ export default function NavBar({ appName, userType }: { appName: string; userTyp
}, },
error: { error: {
render({ data }) { render({ data }) {
return `${data}` return JSON.stringify(data)
}, },
}, },
pending: 'logging out ..', pending: 'logging out ..',
@ -123,7 +112,7 @@ export default function NavBar({ appName, userType }: { appName: string; userTyp
to={`${userProfile.id && '/item/' + userProfile.id}`} to={`${userProfile.id && '/item/' + userProfile.id}`}
className='tw-flex tw-items-center' className='tw-flex tw-items-center'
> >
{userProfile?.image && ( {userProfile.image && (
<div className='tw-avatar'> <div className='tw-avatar'>
<div className='tw-w-10 tw-rounded-full'> <div className='tw-w-10 tw-rounded-full'>
<img src={'https://api.utopia-lab.org/assets/' + userProfile.image} /> <img src={'https://api.utopia-lab.org/assets/' + userProfile.image} />
@ -156,7 +145,7 @@ export default function NavBar({ appName, userType }: { appName: string; userTyp
<li> <li>
<a <a
onClick={() => { onClick={() => {
onLogout() void onLogout()
}} }}
> >
Logout Logout

View File

@ -1,5 +1,3 @@
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unsafe-call */
import { useEffect } from 'react' import { useEffect } from 'react'
export function Modal({ export function Modal({

View File

@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { useAuth } from '#components/Auth' import { useAuth } from '#components/Auth'

View File

@ -4,7 +4,6 @@
/* eslint-disable @typescript-eslint/no-unsafe-argument */ /* eslint-disable @typescript-eslint/no-unsafe-argument */
/* eslint-disable @typescript-eslint/no-unused-vars */ /* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable @typescript-eslint/no-unsafe-call */ /* eslint-disable @typescript-eslint/no-unsafe-call */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/no-non-null-assertion */ /* eslint-disable @typescript-eslint/no-non-null-assertion */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */ /* eslint-disable @typescript-eslint/no-unsafe-member-access */
import { Children, cloneElement, isValidElement, useEffect, useRef, useState } from 'react' import { Children, cloneElement, isValidElement, useEffect, useRef, useState } from 'react'
@ -113,8 +112,8 @@ export function ItemFormPopup(props: ItemFormPopupProps) {
if (!props.layer.onlyOnePerOwner || !item) { if (!props.layer.onlyOnePerOwner || !item) {
addItem({ addItem({
...formItem, ...formItem,
name: formItem.name ? formItem.name : user?.first_name, name: (formItem.name ? formItem.name : user?.first_name) ?? '',
user_created: user, user_created: user ?? undefined,
type: props.layer.itemType, type: props.layer.itemType,
id: uuid, id: uuid,
layer: props.layer, layer: props.layer,

View File

@ -79,7 +79,7 @@ export function ProfileForm() {
const layer = layers.find((l) => l.itemType.name === appState.userType) const layer = layers.find((l) => l.itemType.name === appState.userType)
setItem({ setItem({
id: crypto.randomUUID(), id: crypto.randomUUID(),
name: user ? user.first_name : '', name: user?.first_name ?? '',
text: '', text: '',
layer, layer,
new: true, new: true,

View File

@ -1,6 +1,5 @@
/* eslint-disable @typescript-eslint/no-unnecessary-condition */ /* eslint-disable @typescript-eslint/no-unnecessary-condition */
/* eslint-disable @typescript-eslint/restrict-template-expressions */ /* eslint-disable @typescript-eslint/restrict-template-expressions */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unsafe-return */ /* eslint-disable @typescript-eslint/no-unsafe-return */
/* eslint-disable @typescript-eslint/restrict-plus-operands */ /* eslint-disable @typescript-eslint/restrict-plus-operands */
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'

View File

@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */ /* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/restrict-template-expressions */ /* eslint-disable @typescript-eslint/restrict-template-expressions */
import { TextView } from '#components/Map' import { TextView } from '#components/Map'
@ -14,7 +13,7 @@ export const OnepagerView = ({ item }: { item: Item }) => {
item={item} item={item}
shareBaseUrl={`https://www.wuerdekompass.org/aktivitaeten/gruppensuche/#/gruppe/${item.slug}`} shareBaseUrl={`https://www.wuerdekompass.org/aktivitaeten/gruppensuche/#/gruppe/${item.slug}`}
/> />
{item.user_created.first_name && <ContactInfoView heading='Du hast Fragen?' item={item} />} {item.user_created?.first_name && <ContactInfoView heading='Du hast Fragen?' item={item} />}
{/* Description Section */} {/* Description Section */}
<div className='tw-my-10 tw-mt-2 tw-px-6 tw-text-sm '> <div className='tw-my-10 tw-mt-2 tw-px-6 tw-text-sm '>
<TextView rawText={item.text || 'Keine Beschreibung vorhanden'} /> <TextView rawText={item.text || 'Keine Beschreibung vorhanden'} />

View File

@ -132,7 +132,7 @@ export const TabsView = ({
<table className='sm:tw-table-sm md:tw-table-md'> <table className='sm:tw-table-sm md:tw-table-md'>
<tbody> <tbody>
{attestations {attestations
.filter((a) => a.to.some((t) => t.directus_users_id === item.user_created.id)) .filter((a) => a.to.some((t) => t.directus_users_id === item.user_created?.id))
.sort( .sort(
(a, b) => (a, b) =>
new Date(b.date_created).getTime() - new Date(a.date_created).getTime(), new Date(b.date_created).getTime() - new Date(a.date_created).getTime(),

View File

@ -2,7 +2,6 @@
/* eslint-disable @typescript-eslint/prefer-optional-chain */ /* eslint-disable @typescript-eslint/prefer-optional-chain */
/* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/require-await */ /* eslint-disable @typescript-eslint/require-await */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/no-floating-promises */ /* eslint-disable @typescript-eslint/no-floating-promises */
/* eslint-disable @typescript-eslint/restrict-template-expressions */ /* eslint-disable @typescript-eslint/restrict-template-expressions */
/* eslint-disable @typescript-eslint/restrict-plus-operands */ /* eslint-disable @typescript-eslint/restrict-plus-operands */
@ -49,7 +48,7 @@ export const AttestationForm = ({ api }: { api?: ItemsApi<any> }) => {
const sendAttestation = async () => { const sendAttestation = async () => {
const to: any[] = [] const to: any[] = []
users?.map((u) => to.push({ directus_users_id: u.user_created.id })) users?.map((u) => to.push({ directus_users_id: u.user_created?.id }))
api?.createItem && api?.createItem &&
toast toast
@ -76,7 +75,7 @@ export const AttestationForm = ({ api }: { api?: ItemsApi<any> }) => {
'/item/' + '/item/' +
items.find( items.find(
(i) => (i) =>
i.user_created.id === to[0].directus_users_id && i.user_created?.id === to[0].directus_users_id &&
i.layer?.itemType.name === 'player', i.layer?.itemType.name === 'player',
)?.id + )?.id +
'?tab=2', '?tab=2',

View File

@ -1,5 +1,3 @@
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/restrict-template-expressions */
/* eslint-disable @typescript-eslint/no-non-null-assertion */ /* eslint-disable @typescript-eslint/no-non-null-assertion */
/* eslint-disable @typescript-eslint/no-unnecessary-condition */ /* eslint-disable @typescript-eslint/no-unnecessary-condition */
/* eslint-disable @typescript-eslint/prefer-optional-chain */ /* eslint-disable @typescript-eslint/prefer-optional-chain */

View File

@ -99,7 +99,7 @@ export const OverlayItemsIndexPage = ({
if (success) { if (success) {
toast.success('New item created') toast.success('New item created')
} }
addItem({ ...formItem, user_created: user, id: uuid, layer, public_edit: !user }) addItem({ ...formItem, user_created: user ?? undefined, id: uuid, layer, public_edit: !user })
setLoading(false) setLoading(false)
setAddItemPopupType('') setAddItemPopupType('')
} }

View File

@ -41,7 +41,8 @@ export { TextInput, TextAreaInput, SelectBox } from './Components/Input'
declare global { declare global {
interface Window { interface Window {
// eslint-disable-next-line @typescript-eslint/no-explicit-any my_modal_3: {
my_modal_3: any showModal(): void
}
} }
} }

3
types/Item.d.ts vendored
View File

@ -1,6 +1,7 @@
import type { ItemsApi } from './ItemsApi' import type { ItemsApi } from './ItemsApi'
import type { LayerProps } from './LayerProps' import type { LayerProps } from './LayerProps'
import type { Relation } from './Relation' import type { Relation } from './Relation'
import type { UserItem } from './UserItem'
import type { Point } from 'geojson' import type { Point } from 'geojson'
export interface Item { export interface Item {
@ -21,6 +22,8 @@ export interface Item {
subname?: string subname?: string
public_edit?: boolean public_edit?: boolean
slug?: string slug?: string
user_created?: UserItem
image?: string
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
[key: string]: any [key: string]: any
/* constructor( /* constructor(

1
types/UserItem.d.ts vendored
View File

@ -7,6 +7,7 @@ export interface UserItem {
email?: string email?: string
password?: string password?: string
profile?: Profile profile?: Profile
first_name?: string
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
[key: string]: any [key: string]: any
} }