diff --git a/src/components/DiscoverMinimal.vue b/src/components/DiscoverMinimal.vue new file mode 100644 index 0000000..a2acf17 --- /dev/null +++ b/src/components/DiscoverMinimal.vue @@ -0,0 +1,277 @@ + + + + + Explore Collections + + Curated selections organized by genre, mood, and decade + + + + View All Categories → + View All → + + + + + + + + + Featured Picks + + + + + + + + + + + + diff --git a/src/components/DiscoverShowcase.vue b/src/components/DiscoverShowcase.vue new file mode 100644 index 0000000..1a35122 --- /dev/null +++ b/src/components/DiscoverShowcase.vue @@ -0,0 +1,360 @@ + + + + + + + {{ category.label }} + + {{ category.count }} collections + {{ category.count }} + + + → + + + + + + + + diff --git a/src/components/PageHeader.vue b/src/components/PageHeader.vue index 94280af..fb7b648 100644 --- a/src/components/PageHeader.vue +++ b/src/components/PageHeader.vue @@ -31,12 +31,22 @@ info?: string | Array; link?: string; shortList?: boolean; + sectionType?: "list" | "discover"; } - const props = defineProps(); + const props = withDefaults(defineProps(), { + sectionType: "list" + }); const urlify = computed(() => { - return `/list/${props.title.toLowerCase().replace(" ", "_")}`; + const normalizedTitle = props.title + .toLowerCase() + .replace(/'s\b/g, "") // Remove possessive 's + .replace(/[^\w\d\s-]/g, "") // Remove special characters (keep word chars, dashes, digits, spaces) + .replace(/\s+/g, "_") // Replace spaces with underscores + .replace(/-/g, "_") // Replace dash with underscore + .replace(/_+/g, "_"); // Replace multiple underscores with single underscore + return `/${props.sectionType}/${normalizedTitle}`; }); const prettify = computed(() => { diff --git a/src/components/ResultsSection.vue b/src/components/ResultsSection.vue index 08c051c..84d695c 100644 --- a/src/components/ResultsSection.vue +++ b/src/components/ResultsSection.vue @@ -1,6 +1,8 @@ - + Promise; shortList?: boolean; + sectionType?: "list" | "discover"; } - const props = defineProps(); + const props = withDefaults(defineProps(), { + sectionType: "list" + }); const results: Ref = ref([]); const page: Ref = ref(1); diff --git a/src/components/header/NavigationIcons.vue b/src/components/header/NavigationIcons.vue index c52ed77..234b3ec 100644 --- a/src/components/header/NavigationIcons.vue +++ b/src/components/header/NavigationIcons.vue @@ -15,13 +15,14 @@ import { ref, watch } from "vue"; import { useRoute } from "vue-router"; import NavigationIcon from "@/components/header/NavigationIcon.vue"; - import IconInbox from "@/icons/IconInbox.vue"; + import IconMailboxFull from "@/icons/IconMailboxFull.vue"; import IconNowPlaying from "@/icons/IconNowPlaying.vue"; import IconPopular from "@/icons/IconPopular.vue"; import IconUpcoming from "@/icons/IconUpcoming.vue"; import IconSettings from "@/icons/IconSettings.vue"; import IconActivity from "@/icons/IconActivity.vue"; - import IconBinoculars from "@/icons/IconBinoculars.vue"; + import IconHelm from "@/icons/IconHelm.vue"; + import IconDiscover from "@/icons/IconDiscover.vue"; import type INavigationIcon from "../../interfaces/INavigationIcon"; const route = useRoute(); @@ -30,13 +31,18 @@ { title: "Requests", route: "/list/requests", - icon: IconInbox + icon: IconMailboxFull }, { title: "Now Playing", route: "/list/now_playing", icon: IconNowPlaying }, + { + title: "Discover", + route: "/discover", + icon: IconDiscover + }, { title: "Popular", route: "/list/popular", @@ -58,7 +64,7 @@ title: "Torrents", route: "/torrents", requiresAuth: true, - icon: IconBinoculars + icon: IconHelm }, { title: "Settings", diff --git a/src/icons/IconCalendar.vue b/src/icons/IconCalendar.vue new file mode 100644 index 0000000..db75336 --- /dev/null +++ b/src/icons/IconCalendar.vue @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/src/icons/IconCompass.vue b/src/icons/IconCompass.vue new file mode 100644 index 0000000..933c048 --- /dev/null +++ b/src/icons/IconCompass.vue @@ -0,0 +1,13 @@ + + + + + + + diff --git a/src/icons/IconDiscover.vue b/src/icons/IconDiscover.vue new file mode 100644 index 0000000..24f2dbd --- /dev/null +++ b/src/icons/IconDiscover.vue @@ -0,0 +1,19 @@ + + + + + + + diff --git a/src/icons/IconSpotlights.vue b/src/icons/IconSpotlights.vue new file mode 100644 index 0000000..2c59b66 --- /dev/null +++ b/src/icons/IconSpotlights.vue @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/icons/IconStar.vue b/src/icons/IconStar.vue new file mode 100644 index 0000000..d8d9dc8 --- /dev/null +++ b/src/icons/IconStar.vue @@ -0,0 +1,7 @@ + + + + + diff --git a/src/icons/IconTheater.vue b/src/icons/IconTheater.vue new file mode 100644 index 0000000..9694b14 --- /dev/null +++ b/src/icons/IconTheater.vue @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/src/interfaces/ISection.ts b/src/interfaces/ISection.ts index 6196636..b2b197f 100644 --- a/src/interfaces/ISection.ts +++ b/src/interfaces/ISection.ts @@ -3,4 +3,5 @@ import type { IList } from "./IList"; export default interface ISection { title: string; apiFunction: (page: number) => Promise; + sectionType?: "list" | "discover"; } diff --git a/src/pages/DiscoverPage.vue b/src/pages/DiscoverPage.vue new file mode 100644 index 0000000..c27476b --- /dev/null +++ b/src/pages/DiscoverPage.vue @@ -0,0 +1,514 @@ + + + + + + + + + + + Discover Movies + + Explore curated collections across genres, eras, and moods + + + + + + + + + + + + + + + + diff --git a/src/pages/HomePage.vue b/src/pages/HomePage.vue index 45ec350..5a590ab 100644 --- a/src/pages/HomePage.vue +++ b/src/pages/HomePage.vue @@ -2,38 +2,40 @@ - - - + + + + + + + + + diff --git a/src/pages/ListPage.vue b/src/pages/ListPage.vue deleted file mode 100644 index 4c65e4a..0000000 --- a/src/pages/ListPage.vue +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - diff --git a/src/pages/SectionPage.vue b/src/pages/SectionPage.vue new file mode 100644 index 0000000..412a6c0 --- /dev/null +++ b/src/pages/SectionPage.vue @@ -0,0 +1,40 @@ + + + + + + + diff --git a/src/routes.ts b/src/routes.ts index 3bc48af..b636375 100644 --- a/src/routes.ts +++ b/src/routes.ts @@ -39,7 +39,17 @@ const routes: RouteRecordRaw[] = [ { name: "list", path: "/list/:name", - component: () => import("./pages/ListPage.vue") + component: () => import("./pages/SectionPage.vue") + }, + { + name: "discover-section", + path: "/discover/:name", + component: () => import("./pages/SectionPage.vue") + }, + { + name: "discover", + path: "/discover", + component: () => import("./pages/DiscoverPage.vue") }, { name: "search", @@ -104,7 +114,13 @@ const router = createRouter({ history: createWebHistory("/"), // base: "/", routes, - linkActiveClass: "is-active" + linkActiveClass: "is-active", + scrollBehavior(to, from, savedPosition) { + if (to.name !== "discover") return; + + console.log("scrolling top"); + return { top: 0 }; + } }); const loggedIn = () => store.getters["user/loggedIn"];
+ Curated selections organized by genre, mood, and decade +
+ {{ category.count }} collections + {{ category.count }} +
+ Explore curated collections across genres, eras, and moods +