diff --git a/src/features/SongLists/SongLists.tsx b/src/features/SongLists/SongLists.tsx
index f1a5547..75530f5 100644
--- a/src/features/SongLists/SongLists.tsx
+++ b/src/features/SongLists/SongLists.tsx
@@ -1,9 +1,7 @@
import React, { useState, useMemo, useCallback } from 'react';
-import { IonItem, IonModal, IonHeader, IonToolbar, IonTitle, IonChip, IonContent, IonList, IonAccordionGroup, IonAccordion } from '@ionic/react';
+import { IonItem, IonModal, IonChip, IonContent, IonList, IonAccordionGroup, IonAccordion } from '@ionic/react';
import { list } from 'ionicons/icons';
-import { InfiniteScrollList, SongItem, ListItem, TwoLineDisplay, NumberDisplay, ActionButton } from '../../components/common';
-import { ActionButtonVariant, ActionButtonSize, ActionButtonIconSlot } from '../../types';
-import { Icons } from '../../constants';
+import { InfiniteScrollList, SongItem, ListItem, TwoLineDisplay, NumberDisplay, ModalHeader } from '../../components/common';
import { useSongLists } from '../../hooks';
import { useAppSelector } from '../../redux';
import { selectSongList } from '../../redux';
@@ -90,21 +88,7 @@ const SongLists: React.FC = () => {
isOpen={!!finalSelectedList}
onDidDismiss={handleCloseSongList}
>
-
-
- {finalSelectedList?.title}
-
-
-
+
diff --git a/src/features/TopPlayed/Top100.tsx b/src/features/TopPlayed/Top100.tsx
index 526e196..3cd91c6 100644
--- a/src/features/TopPlayed/Top100.tsx
+++ b/src/features/TopPlayed/Top100.tsx
@@ -1,15 +1,14 @@
import React, { useState, useMemo, useCallback } from 'react';
-import { IonChip, IonModal, IonHeader, IonToolbar, IonTitle, IonIcon, IonContent, IonList } from '@ionic/react';
+import { IonChip, IonModal, IonIcon, IonContent, IonList } from '@ionic/react';
import { list } from 'ionicons/icons';
import { useTopPlayed } from '../../hooks';
import { useAppSelector } from '../../redux';
import { selectTopPlayed, selectSongsArray } from '../../redux';
-import { InfiniteScrollList, SongItem, ListItem, ActionButton } from '../../components/common';
+import { InfiniteScrollList, SongItem, ListItem, ModalHeader } from '../../components/common';
import { filterSongs } from '../../utils/dataProcessing';
import { debugLog } from '../../utils/logger';
-import { ActionButtonVariant, ActionButtonSize, ActionButtonIconSlot } from '../../types';
-import { Icons } from '../../constants';
+
import type { TopPlayed } from '../../types';
const Top100: React.FC = () => {
@@ -117,21 +116,7 @@ const Top100: React.FC = () => {
breakpoints={[0, 0.5, 0.8]}
initialBreakpoint={0.8}
>
-
-
- {selectedTopPlayed?.artist}
-
-
-
+
diff --git a/src/hooks/index.ts b/src/hooks/index.ts
index 8cb7628..2e1b9b8 100644
--- a/src/hooks/index.ts
+++ b/src/hooks/index.ts
@@ -11,5 +11,5 @@ export { useArtists } from './useArtists';
export { useSingers } from './useSingers';
export { useSongLists } from './useSongLists';
export { useDisabledSongs } from './useDisabledSongs';
-export { useSelectSinger } from './useSelectSinger';
+
export { useSongInfo } from './useSongInfo';
\ No newline at end of file
diff --git a/src/hooks/useModalContext.ts b/src/hooks/useModalContext.ts
new file mode 100644
index 0000000..ef42f51
--- /dev/null
+++ b/src/hooks/useModalContext.ts
@@ -0,0 +1,12 @@
+import { useContext } from 'react';
+import { ModalContext } from '../contexts/ModalContext';
+
+export const useModal = () => {
+ const context = useContext(ModalContext);
+
+ if (context === undefined) {
+ throw new Error('useModal must be used within a ModalProvider');
+ }
+
+ return context;
+};
\ No newline at end of file
diff --git a/src/hooks/useSelectSinger.ts b/src/hooks/useSelectSinger.ts
deleted file mode 100644
index b132175..0000000
--- a/src/hooks/useSelectSinger.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import { useState, useCallback } from 'react';
-import type { Song } from '../types';
-
-export const useSelectSinger = () => {
- const [isOpen, setIsOpen] = useState(false);
- const [selectedSong, setSelectedSong] = useState(null);
-
- const openSelectSinger = useCallback((song: Song) => {
- setSelectedSong(song);
- setIsOpen(true);
- }, []);
-
- const closeSelectSinger = useCallback(() => {
- setIsOpen(false);
- setSelectedSong(null);
- }, []);
-
- return {
- isOpen,
- selectedSong,
- openSelectSinger,
- closeSelectSinger,
- };
-};
\ No newline at end of file
diff --git a/src/hooks/useSongInfoContext.ts b/src/hooks/useSongInfoContext.ts
deleted file mode 100644
index c20ccc9..0000000
--- a/src/hooks/useSongInfoContext.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { useContext } from 'react';
-import { SongInfoContext, type SongInfoContextType } from '../contexts/SongInfoContext';
-
-export const useSongInfo = (): SongInfoContextType => {
- const context = useContext(SongInfoContext);
- if (context === null) {
- throw new Error('useSongInfo must be used within a SongInfoProvider');
- }
- return context;
-};
\ No newline at end of file
diff --git a/src/types/index.ts b/src/types/index.ts
index de9d17b..94e35bc 100644
--- a/src/types/index.ts
+++ b/src/types/index.ts
@@ -160,6 +160,7 @@ export interface ActionButtonProps {
iconSlot?: ActionButtonIconSlotType;
iconSize?: ActionButtonIconSizeType;
fill?: 'solid' | 'outline' | 'clear';
+ 'aria-label'?: string;
}
export interface SongItemProps {
@@ -195,4 +196,8 @@ export interface RootState {
loading: boolean;
error: string | null;
};
-}
\ No newline at end of file
+}
+
+// Modal types
+export { ModalType } from './modal';
+export type { ModalViewType, ModalState, ModalContextType, ModalItem } from './modal';
\ No newline at end of file
diff --git a/src/types/modal.ts b/src/types/modal.ts
new file mode 100644
index 0000000..6e35265
--- /dev/null
+++ b/src/types/modal.ts
@@ -0,0 +1,33 @@
+import type { Song } from './index';
+
+export const ModalType = {
+ SONG_INFO: 'songInfo',
+ SELECT_SINGER: 'selectSinger'
+} as const;
+
+export type ModalViewType = typeof ModalType[keyof typeof ModalType];
+
+export interface ModalItem {
+ id: string;
+ type: ModalViewType;
+ data: Song;
+ isOpen: boolean;
+}
+
+export interface ModalState {
+ stack: ModalItem[];
+}
+
+export interface ModalContextType {
+ // Generic modal methods
+ openModal: (type: ModalViewType, data: Song) => string; // Returns modal ID
+ closeModal: (id: string) => void;
+ closeTopModal: () => void;
+
+ // Specific modal methods for convenience
+ openSongInfo: (song: Song) => string;
+ openSelectSinger: (song: Song) => string;
+
+ // State
+ modalState: ModalState;
+}
\ No newline at end of file