Skip to content

Commit

Permalink
Update .gitignore, refactor Header component for type safety, and adj…
Browse files Browse the repository at this point in the history
…ust API URLs in context files
  • Loading branch information
PentSec committed Jan 20, 2025
1 parent 2c48154 commit 7efcf7f
Show file tree
Hide file tree
Showing 13 changed files with 219 additions and 163 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ lerna-debug.log*
MaddonsManager.github.io.code-workspace
.react-router/

.env
.env.production
.env.development
node_modules
dist
dist-ssr
Expand Down
2 changes: 1 addition & 1 deletion src/components/Header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ interface HeaderProps {
const Header = ({ data }: HeaderProps) => {
const { pathname } = useLocation()

const getPageLabel = () => {
const getPageLabel = (): string | undefined => {
const allNavItems = [...siteConfig.navItems, ...siteConfig.navItemsAccord]
return allNavItems.find((item) => item.href.toLowerCase() === pathname.toLowerCase())?.label
}
Expand Down
6 changes: 3 additions & 3 deletions src/components/ItemList/ItemList.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Card, CardBody, Image, Button, Tooltip, Chip, Avatar, Divider } from "@heroui/react"
import { Card, CardBody, Image, Button, Tooltip, Chip, Avatar, Divider } from '@heroui/react'
import { AnimatePresence } from 'framer-motion'
import { classIcon } from '@/utils/classIcon'
import { FlameIcon, GroupIcon } from '@/assets/Icons'
Expand All @@ -16,7 +16,7 @@ const ItemList = ({ data, onOpenDetails, handleCopyToClipboard, itemToShow }: It
<AnimatePresence>
{data.slice(0, itemToShow).map((item: StringItems) => (
<div
key={`${item.uuid}-${item.title}`}
key={`${item.file_name}-${item.title}`}
className="transition-transform duration-300 ease-in-out hover:scale-105"
>
<Card
Expand Down Expand Up @@ -67,7 +67,7 @@ const ItemList = ({ data, onOpenDetails, handleCopyToClipboard, itemToShow }: It
item.class.map((className: string, index: number) => (
<Chip
avatar={
className === 'ALL' ? (
className === 'All' ? (
<GroupIcon />
) : (
<Avatar
Expand Down
39 changes: 13 additions & 26 deletions src/components/ProfilesDetails/ProfilesDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ import {
Chip,
Image,
Avatar
} from "@heroui/react"
} from '@heroui/react'
import ReactMarkdown from 'react-markdown'
import { classIcon, roleIcon } from '@/utils/classIcon'
import remarkGfm from 'remark-gfm'
import rehypeRaw from 'rehype-raw'
import hljs from 'highlight.js'
import { useEffect } from 'react'
import { GroupIcon } from '@/assets/Icons'

interface ProfilesDetailsProps {
data: any
Expand Down Expand Up @@ -67,10 +68,14 @@ const ProfilesDetails = ({ data, isOpen, onOpenChange }: ProfilesDetailsProps) =
{data.class.map((className: string, index: number) => (
<Chip
avatar={
<Avatar
name={data.title}
src={classIcon[className]}
/>
className === 'All' ? (
<GroupIcon />
) : (
<Avatar
name={data.title}
src={classIcon[className]}
/>
)
}
key={index}
color="warning"
Expand Down Expand Up @@ -107,38 +112,20 @@ const ProfilesDetails = ({ data, isOpen, onOpenChange }: ProfilesDetailsProps) =
<Divider className="my-2" />
<div className="flex items-center justify-between">
<p className=" text-white/60">95.1k Downloads - 141.9k views</p>
<p className="text-sm text-gray-500">
Last updated: {data.lastUpdate}
</p>
<p className="text-sm text-gray-500">version: {data.version}</p>
<p className="text-sm text-gray-500">Last updated:</p>
<p className="text-sm text-gray-500">version: </p>
</div>
<Divider className="my-2" />
<h2 className="text-lg font-extrabold">Description</h2>
<article className="markdown-body p-1 !bg-transparent">
<ReactMarkdown
remarkPlugins={[remarkGfm]}
rehypePlugins={[rehypeRaw]}
className="text-default-900 gap-4 w-auto p-4 mx-auto flex-col lg:flex-row rounded-md"
>
{data.md}
</ReactMarkdown>
</article>
<div className="flex justify-center p-4 ">
<Image
shadow="md"
alt={data.title}
radius="sm"
src={data.logo}
className="max-w-[500px] max-h-[500px]"
/>
</div>
<div className="flex flex-col items-start justify-center p-4">
<h2 className="text-lg font-extrabold">Changelogs</h2>
{data.changelog.map((changelog: string, index: number) => (
<p key={index} className="block my-2 text-justify">
{changelog}
</p>
))}
</div>
</DrawerBody>
<DrawerFooter>
<Button color="primary" onPress={onClose}>
Expand Down
8 changes: 4 additions & 4 deletions src/components/Searcher/Searcher.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Autocomplete, AutocompleteItem } from "@heroui/react"
import { Autocomplete, AutocompleteItem } from '@heroui/react'
import { SearchIcon } from '@/assets/Icons'

interface SearcherProps {
Expand All @@ -14,7 +14,7 @@ const SearchAddon = ({ searchTerm, setSearchTerm, valueName }: SearcherProps) =>
isVirtualized
selectedKey={searchTerm}
onSelectionChange={(key) => setSearchTerm(key as string)}
defaultItems={valueName.map((name) => ({ key: name, name: name }))}
defaultItems={valueName.map((title) => ({ key: title, title: title }))}
startContent={<SearchIcon className="w-4 h-4" />}
size="md"
className="w-full font-bold text-default-900"
Expand Down Expand Up @@ -46,8 +46,8 @@ const SearchAddon = ({ searchTerm, setSearchTerm, valueName }: SearcherProps) =>
}}
>
{(item) => (
<AutocompleteItem key={item.key} textValue={item.name}>
{item.name}
<AutocompleteItem key={item.key} textValue={item.title}>
{item.title}
</AutocompleteItem>
)}
</Autocomplete>
Expand Down
63 changes: 30 additions & 33 deletions src/context/AddonsContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,11 @@ import { createContext, FC, ReactNode, useContext } from 'react'
import { useQuery } from '@tanstack/react-query'
import { AddonsDataState } from '@/types'

const urls: { [key: string]: string } = {
LichKing: 'https://raw.githubusercontent.com/PentSec/wowAddonsAPI/main/LK/lichking.json',
Cataclysm: 'https://raw.githubusercontent.com/PentSec/wowAddonsAPI/main/Cata/cataclysm.json',
Pandaria: 'https://raw.githubusercontent.com/PentSec/wowAddonsAPI/main/Panda/pandaria.json'
}
const jsonUrl =
'https://raw.githubusercontent.com/PentSec/MaddonsManager/refs/heads/main/API/Maddons.json'

interface AddonsContextValue {
data: AddonsDataState
data: AddonsDataState[]
isPending: boolean
error: string | null
}
Expand All @@ -24,41 +21,41 @@ export const useAddonsContext = (): AddonsContextValue => {
return context
}

const fetchAddons = async (key: string) => {
const response = await fetch(urls[key]).then((res) => res.json())
return response
const fetchAddons = async (url: string) => {
const response = await fetch(url)
const jsonData = await response.json()
return Promise.all(
jsonData.map(async (item: AddonsDataState) => {
const mdUrl = `https://raw.githubusercontent.com/PentSec/MaddonsManager/refs/heads/main/API/Addons/${item.file_name}/post.md`
const logoUrl = `https://raw.githubusercontent.com/PentSec/MaddonsManager/refs/heads/main/API/Addons/${item.file_name}/${item.file_name}.webp`
const zipUrl = `https://github.com/PentSec/MaddonsManager/raw/refs/heads/main/API/Addons/${item.file_name}/${item.file_name}.zip`

const [md] = await Promise.all([
fetch(mdUrl).then((res) => {
if (!res.ok) throw new Error(`Failed to fetch md for ${item.file_name}`)
return res.text()
})
])

return { ...item, md, logo: logoUrl, zip: zipUrl }
})
)
}

export const AddonsProvider: FC<{ children: ReactNode }> = ({ children }) => {
const lichKingQuery = useQuery({
queryKey: ['lichKing'],
queryFn: () => fetchAddons('LichKing'),
refetchOnWindowFocus: false
})
const cataclysmQuery = useQuery({
queryKey: ['cataclysm'],
queryFn: () => fetchAddons('Cataclysm'),
refetchOnWindowFocus: false
})
const pandariaQuery = useQuery({
queryKey: ['pandaria'],
queryFn: () => fetchAddons('Pandaria'),
const { data, isPending, error } = useQuery({
queryKey: ['addons'],
queryFn: () => fetchAddons(jsonUrl),
refetchOnWindowFocus: false
})

const data: AddonsDataState = {
LichKing: lichKingQuery.data || [],
Cataclysm: cataclysmQuery.data || [],
Pandaria: pandariaQuery.data || []
}

const isPending = lichKingQuery.isPending || cataclysmQuery.isPending || pandariaQuery.isPending

const error = lichKingQuery.error || cataclysmQuery.error || pandariaQuery.error

return (
<AddonsContext.Provider
value={{ data, isPending, error: error ? (error as Error).message : null }}
value={{
data: data || [],
isPending,
error: error ? (error as Error).message : null
}}
>
{children}
</AddonsContext.Provider>
Expand Down
12 changes: 6 additions & 6 deletions src/context/ElvUIContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { createContext, useContext, FC, ReactNode } from 'react'
import { StringItems } from '@/types'
import { useQuery } from '@tanstack/react-query'

const jsonUrl = 'https://raw.githubusercontent.com/PentSec/wowAddonsAPI/develop/ElvUI/ElvUI.json'
const jsonUrl = 'https://raw.githubusercontent.com/PentSec/MaddonsManager/main/API/ElvUI.json'

interface ElvUIContextValue {
data: StringItems[]
Expand All @@ -25,17 +25,17 @@ const fetchElvUIWithContent = async (url: string): Promise<StringItems[]> => {
const jsonData = await response.json()
return Promise.all(
jsonData.map(async (item: StringItems) => {
const txtUrl = `https://raw.githubusercontent.com/PentSec/wowAddonsAPI/develop/ElvUI/${item.uuid}/${item.uuid}.txt`
const logoUrl = `https://raw.githubusercontent.com/PentSec/wowAddonsAPI/develop/ElvUI/${item.uuid}/${item.logo}`
const mdUrl = `https://raw.githubusercontent.com/PentSec/wowAddonsAPI/develop/ElvUI/${item.uuid}/${item.uuid}.md`
const txtUrl = `https://raw.githubusercontent.com/PentSec/MaddonsManager/main/API/ElvUI/${item.file_name}/${item.file_name}.txt`
const logoUrl = `https://raw.githubusercontent.com/PentSec/MaddonsManager/main/API/ElvUI/${item.file_name}/${item.file_name}.webp`
const mdUrl = `https://raw.githubusercontent.com/PentSec/MaddonsManager/main/API/ElvUI/${item.file_name}/post.md`

const [content, md] = await Promise.all([
fetch(txtUrl).then((res) => {
if (!res.ok) throw new Error(`Failed to fetch txt for ${item.uuid}`)
if (!res.ok) throw new Error(`Failed to fetch txt for ${item.file_name}`)
return res.text()
}),
fetch(mdUrl).then((res) => {
if (!res.ok) throw new Error(`Failed to fetch md for ${item.uuid}`)
if (!res.ok) throw new Error(`Failed to fetch md for ${item.file_name}`)
return res.text()
})
])
Expand Down
9 changes: 4 additions & 5 deletions src/context/WeakAurasContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import { createContext, FC, ReactNode, useContext } from 'react'
import { useQuery } from '@tanstack/react-query'
import { StringItems } from '@/types'

const jsonUrl =
'https://raw.githubusercontent.com/PentSec/wowAddonsAPI/develop/WeakAuras/WeakAuras.json'
const jsonUrl = 'https://raw.githubusercontent.com/PentSec/MaddonsManager/main/API/WeakAuras.json'

interface WeakAurasContextValue {
data: StringItems[]
Expand All @@ -26,9 +25,9 @@ const fetchWeakAurasWithContent = async (url: string): Promise<StringItems[]> =>
const jsonData = await response.json()
return Promise.all(
jsonData.map(async (item: any) => {
const txtUrl = `https://raw.githubusercontent.com/PentSec/wowAddonsAPI/develop/WeakAuras/${item.uuid}/${item.uuid}.txt`
const logoUrl = `https://raw.githubusercontent.com/PentSec/wowAddonsAPI/develop/WeakAuras/${item.uuid}/${item.logo}`
const mdUrl = `https://raw.githubusercontent.com/PentSec/wowAddonsAPI/develop/WeakAuras/${item.uuid}/${item.uuid}.md`
const txtUrl = `https://raw.githubusercontent.com/PentSec/MaddonsManager/main/API/WeakAuras/${item.file_name}/${item.file_name}.txt`
const logoUrl = `https://raw.githubusercontent.com/PentSec/MaddonsManager/main/API/WeakAuras/${item.file_name}/${item.file_name}.webp`
const mdUrl = `https://raw.githubusercontent.com/PentSec/MaddonsManager/main/API/WeakAuras/${item.file_name}/post.md`

const [content, md] = await Promise.all([
fetch(txtUrl).then((res) => (res.ok ? res.text() : null)),
Expand Down
42 changes: 16 additions & 26 deletions src/hook/useFilterAddons.ts
Original file line number Diff line number Diff line change
@@ -1,44 +1,35 @@
import { useState, useMemo } from 'react'
import { AddonsData, AddonsDataState } from '@/types'

const useFilterAddons = (data: AddonsDataState | null, onOpen: (isOpen: boolean) => void) => {
const useFilterAddons = (data: AddonsDataState[], onOpen: () => void) => {
const [searchTerm, setSearchTerm] = useState<string | null>(null)
const [version, setVersion] = useState<string | null>(null)
const [selectedType, setSelectedType] = useState<string | null>(null)
const [isSelectAddon, setIsSelectAddon] = useState<AddonsData | null>(null)

const combinedData = useMemo(() => {
if (!data) return []
const allData = [...data.LichKing, ...data.Cataclysm, ...data.Pandaria]
return version === null ? allData : data[version] || []
}, [data, version])
if (!data || data.length === 0) return []
return Array.from(new Set(data.flatMap((item) => item.expansion)))
}, [data])

const addonTypes = useMemo(() => {
return combinedData && combinedData.length > 0
? Array.from(new Set(combinedData.map((addon) => addon.addonType)))
: []
}, [combinedData])
return Array.from(new Set(data.flatMap((item) => item.tags)))
}, [data])

const filteredData = useMemo(() => {
return (
combinedData?.filter((addon) => {
const matchesSearch = searchTerm
? addon.name.toLowerCase().includes(searchTerm.toLowerCase())
: true
const matchesType = selectedType ? addon.addonType === selectedType : true
return matchesSearch && matchesType
}) || []
)
}, [combinedData, searchTerm, selectedType])

const handleDownload = async (githubRepo: string) => {
const mainUrl = `${githubRepo}/archive/refs/heads/main.zip`
window.open(mainUrl)
}
return data.filter((item) => {
const matchesSearch = searchTerm
? item.title.toLowerCase().includes(searchTerm.toLowerCase())
: true
const matchesType = selectedType ? item.tags.includes(selectedType) : true
const matchesExpansion = version ? item.expansion.includes(version) : true
return matchesSearch && matchesType && matchesExpansion
})
}, [data, searchTerm, selectedType, version])

const handleOpenDetails = (addon: AddonsData) => {
setIsSelectAddon(addon)
onOpen(true)
onOpen()
}

return {
Expand All @@ -51,7 +42,6 @@ const useFilterAddons = (data: AddonsDataState | null, onOpen: (isOpen: boolean)
addonTypes,
filteredData,
combinedData,
handleDownload,
handleOpenDetails,
isSelectAddon
}
Expand Down
Loading

0 comments on commit 7efcf7f

Please sign in to comment.