src/
├── App.tsx
├── index.css
├── lib/jikan.ts
├── components/
│ ├── AnimeCard.tsx
│ └── Sidebar.tsx
├── pages/
│ ├── layout/AppLayout.tsx
│ ├── home/page.tsx
│ ├── anime/page.tsx
│ ├── watch/page.tsx
│ ├── search/page.tsx
│ ├── favorites/page.tsx
│ └── history/page.tsx
convex/
├── schema.ts
└── users.ts
import { BrowserRouter, Route, Routes } from "react-router-dom";
import { DefaultProviders } from "./components/providers/default.tsx";
import AuthCallback from "./pages/auth/Callback.tsx";
import AppLayout from "./pages/layout/AppLayout.tsx";
import HomePage from "./pages/home/page.tsx";
import AnimeDetailPage from "./pages/anime/page.tsx";
import WatchPage from "./pages/watch/page.tsx";
import SearchPage from "./pages/search/page.tsx";
import FavoritesPage from "./pages/favorites/page.tsx";
import HistoryPage from "./pages/history/page.tsx";
import NotFound from "./pages/NotFound.tsx";
export default function App() {
return (
} />
}>
} />
} />
} />
} />
} />
} />
} />
);
}
const BASE_URL = "https://api.jikan.moe/v4";
export type AnimeItem = { /* ... */ };
export type AnimeEpisode = { /* ... */ };
export type AnimeStreamingLink = { name: string; url: string; };
export async function getTopAnime(page = 1): Promise
export async function getSeasonalAnime(): Promise
export async function getAnimeById(id: number): Promise
export async function searchAnime(query: string): Promise
export async function getAiringAnime(): Promise
export async function getAnimeEpisodes(id: number, page = 1)
export async function getAnimeStreaming(id: number): Promise
users: defineTable({
tokenIdentifier: v.string(),
name: v.optional(v.string()),
email: v.optional(v.string()),
}).index("by_token", ["tokenIdentifier"])
--background: oklch(0.08 0 0); /* أسود داكن */
--primary: oklch(0.78 0.18 85); /* ذهبي */
--card: oklch(0.12 0 0); /* رمادي داكن */