Skip to content
Snippets Groups Projects
Commit 37f33681 authored by Tejas's avatar Tejas
Browse files

Navbar changed, Home started.

parent b9e61446
No related branches found
No related tags found
2 merge requests!5Push to Main,!1Profile view implemented, watchlist view and component implemented with a...
......@@ -5,7 +5,7 @@ import Navbar from './components/Navbar.vue';
<template>
<Navbar />
<div class="pt-20">
<div class="pt-20 z-10 bg-neutral-900">
<RouterView />
</div>
</template>
......
<template>
<nav class="fixed top-0 left-0 w-full bg-gray-800 text-white shadow-md pr-4 pl-4 flex justify-between items-center">
<!-- Logo -->
<div class="flex items-center space-x-3">
<img class="h-20 w-auto" src="../assets/Dark_Mode.png" alt="Logo" />
<nav class="fixed top-0 left-0 right-0 min-w-11/12 mx-6 bg-neutral-800 text-white shadow-md px-4 flex justify-between items-center z-50 rounded-2xl mt-3">
<!-- Logo -->
<div class="flex items-center">
<RouterLink to="/">
<img class="h-14 w-auto" src="../assets/Dark_Mode.png" alt="Logo" />
</RouterLink>
</div>
<!-- Search Bar (Perfectly Centered) -->
<div class="absolute left-1/2 transform -translate-x-1/2 w-full max-w-md">
<input
v-model="searchQuery"
type="text"
placeholder="Search..."
class="w-full px-4 py-2 pr-10 rounded-full bg-neutral-700 text-white placeholder-gray-400 focus:ring-2 focus:ring-white focus:outline-none"
/>
<!-- Search Icon inside input -->
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"
class="size-6 absolute right-3 top-1/2 -translate-y-1/2 text-gray-400">
<path stroke-linecap="round" stroke-linejoin="round"
d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z" />
</svg>
</div>
<!-- Navigation & Profile Section -->
<div class="flex items-center space-x-4 ml-auto">
<!-- Navigation Links -->
<div class="flex space-x-3">
<RouterLink
v-for="item in filteredNavigation"
:key="item.name"
:to="item.href"
class="px-3 py-2 rounded-md text-sm font-medium transition hover:bg-gray-700"
:class="{ 'bg-gray-900': item.href === currentRoute }">
class="px-3 py-2 rounded-md text-sm font-medium transition hover:bg-neutral-700"
:class="{ 'bg-neutral-900': item.href === currentRoute }">
{{ item.name }}
</RouterLink>
<RouterLink
v-if="!isLoggedIn"
to="/login"
class="px-4 py-2 rounded-xl bg-blue-600 text-white font-semibold text-sm transition hover:bg-blue-700 shadow-md">
Login
</RouterLink>
</div>
<!-- Profile & Notifications -->
<div class="flex items-center space-x-4">
<!-- Notifications -->
<!-- <button class="relative p-2 rounded-full text-gray-400 hover:text-white hover:bg-gray-700">
<BellIcon class="h-6 w-6" aria-hidden="true" />
</button> -->
<!-- Profile Dropdown (Only show if logged in) -->
<Menu as="div" class="relative" v-if="isLoggedIn">
<div>
<MenuButton class="flex rounded-full bg-gray-800 text-sm focus:ring-2 focus:ring-white focus:ring-offset-2">
<img class="h-8 w-8 rounded-full" src="https://randomuser.me/api/portraits/men/1.jpg" alt="User Avatar" />
</MenuButton>
</div>
<transition enter-active-class="transition ease-out duration-100" enter-from-class="transform opacity-0 scale-95" enter-to-class="transform opacity-100 scale-100" leave-active-class="transition ease-in duration-75" leave-from-class="transform opacity-100 scale-100" leave-to-class="transform opacity-0 scale-95">
<MenuItems class="absolute right-0 mt-2 w-48 bg-white rounded-md shadow-lg ring-1 ring-black/5 py-1">
<MenuItem v-slot="{ active }">
<RouterLink to="/profile" :class="[active ? 'bg-gray-100' : '', 'block px-4 py-2 text-sm text-gray-700']">Your Profile</RouterLink>
</MenuItem>
<MenuItem v-slot="{ active }">
<RouterLink to="/settings" :class="[active ? 'bg-gray-100' : '', 'block px-4 py-2 text-sm text-gray-700']">Settings</RouterLink>
</MenuItem>
<MenuItem @click="handleSignOut" v-slot="{ active }">
<a href="#" @click.prevent="handleSignOut" :class="[active ? 'bg-gray-100' : '', 'block px-4 py-2 text-sm text-gray-700']">Sign out</a>
</MenuItem>
</MenuItems>
</transition>
</Menu>
</div>
</nav>
</template>
<script setup>
import { ref, computed, onMounted } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { getAuth, onAuthStateChanged, signOut } from 'firebase/auth';
import { Menu, MenuButton, MenuItem, MenuItems } from '@headlessui/vue';
import { BellIcon } from '@heroicons/vue/24/outline';
// Firebase Authentication instance
const auth = getAuth();
const route = useRoute();
const router = useRouter();
const isLoggedIn = ref(false);
const navigation = ref([
{ name: 'Home', href: '/' },
{ name: 'Feed', href: '/feed', authRequired: true },
{ name: 'Register', href: '/register', guestOnly: true },
{ name: 'Login', href: '/login', guestOnly: true },
]);
// Compute the current route to match against the navigation links
const currentRoute = computed(() => route.path);
// Filter navigation based on auth state
const filteredNavigation = computed(() => {
return navigation.value.filter(item => {
if (item.authRequired && !isLoggedIn.value) return false; // Hide if user is not logged in
if (item.guestOnly && isLoggedIn.value) return false; // Hide if user is logged in
return true;
});
<!-- Profile Dropdown (Only show if logged in) -->
<Menu as="div" class="relative" v-if="isLoggedIn">
<div>
<MenuButton class="flex rounded-full bg-gray-800 text-sm focus:ring-1 focus:ring-white focus:ring-offset-2">
<img class="h-8 w-8 rounded-full" src="https://randomuser.me/api/portraits/men/1.jpg" alt="User Avatar" />
</MenuButton>
</div>
<transition enter-active-class="transition ease-out duration-100" enter-from-class="transform opacity-0 scale-95" enter-to-class="transform opacity-100 scale-100" leave-active-class="transition ease-in duration-75" leave-from-class="transform opacity-100 scale-100" leave-to-class="transform opacity-0 scale-95">
<MenuItems class="absolute right-0 mt-2 w-48 bg-neutral-800 rounded-md shadow-lg ring-1 ring-black/5 py-1">
<MenuItem v-slot="{ active }">
<RouterLink to="/profile" :class="[active ? 'bg-neutral-700' : '', 'block px-4 py-2 text-sm text-white']">Your Profile</RouterLink>
</MenuItem>
<MenuItem v-slot="{ active }">
<RouterLink to="/settings" :class="[active ? 'bg-neutral-700' : '', 'block px-4 py-2 text-sm text-white']">Settings</RouterLink>
</MenuItem>
<MenuItem @click="handleSignOut" v-slot="{ active }">
<a href="#" @click.prevent="handleSignOut" :class="[active ? 'bg-neutral-700' : '', 'block px-4 py-2 text-sm text-white']">Sign out</a>
</MenuItem>
</MenuItems>
</transition>
</Menu>
</div>
</nav>
</template>
<script setup>
import { ref, computed, onMounted } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { getAuth, onAuthStateChanged, signOut } from 'firebase/auth';
import { Menu, MenuButton, MenuItem, MenuItems } from '@headlessui/vue';
// Firebase Authentication instance
const auth = getAuth();
const route = useRoute();
const router = useRouter();
const isLoggedIn = ref(false);
const navigation = ref([
{ name: 'Films', href: '/films', authRequired: true },
{ name: 'Watchlist', href: '/watchlist', authRequired: true },
]);
// Compute the current route to match against the navigation links
const currentRoute = computed(() => route.path);
// Filter navigation based on auth state
const filteredNavigation = computed(() => {
return navigation.value.filter(item => {
if (item.authRequired && !isLoggedIn.value) return false; // Hide if user is not logged in
if (item.guestOnly && isLoggedIn.value) return false; // Hide if user is logged in
return true;
});
// Check authentication state
onMounted(() => {
onAuthStateChanged(auth, (user) => {
isLoggedIn.value = !!user; // Sets to true if user exists, false otherwise
});
});
// Check authentication state
onMounted(() => {
onAuthStateChanged(auth, (user) => {
isLoggedIn.value = !!user; // Sets to true if user exists, false otherwise
});
// Sign-out function
const handleSignOut = () => {
signOut(auth)
.then(() => {
isLoggedIn.value = false; // Ensure UI updates correctly
router.push('/'); // Redirect to home
})
.catch((error) => {
console.error("Error signing out:", error);
});
};
</script>
});
// Sign-out function
const handleSignOut = () => {
signOut(auth)
.then(() => {
isLoggedIn.value = false; // Ensure UI updates correctly
router.push('/'); // Redirect to home
})
.catch((error) => {
console.error("Error signing out:", error);
});
};
</script>
......@@ -8,10 +8,15 @@ const router = createRouter({
{ path: '/register', component: () => import('../views/Register.vue') },
{ path: '/login', component: () => import('../views/Login.vue') },
{
path: '/feed',
component: () => import('../views/Feed.vue'),
path: '/films',
component: () => import('../views/Films.vue'),
meta: { requiresAuth: true },
},
{
path: '/watchlist',
component: () => import('../views/Watchlist.vue'),
meta: { requiresAuth: true },
},
],
});
......
<template>Feed</template>
\ No newline at end of file
<template>Films</template>
\ No newline at end of file
<template>Home</template>
\ No newline at end of file
<template>
<div class="h-full bg-neutral-900">
<!-- Features -->
<div class="max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 mx-auto dark">
<div class="relative p-6 md:p-16">
<!-- Grid -->
<div class="relative z-10 lg:grid lg:grid-cols-12 lg:gap-16 lg:items-center">
<div class="mb-10 lg:mb-0 lg:col-span-6 lg:col-start-8 lg:order-2">
<h2 class="text-2xl text-neutral-200 font-bold sm:text-3xl">
Fully customizable rules to match your unique needs
</h2>
<!-- Tab Navs -->
<nav class="grid gap-4 mt-5 md:mt-10" aria-label="Tabs" role="tablist" aria-orientation="vertical">
<button type="button" class="hs-tab-active:bg-neutral-700 hs-tab-active:shadow-md text-start hover:bg-neutral-700 focus:bg-neutral-700 p-4 md:p-5 rounded-xl active" id="tabs-with-card-item-1" aria-selected="true" data-hs-tab="#tabs-with-card-1" aria-controls="tabs-with-card-1" role="tab">
<span class="flex gap-x-6">
<svg class="shrink-0 mt-2 size-6 md:size-7 text-blue-500" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 5.5A3.5 3.5 0 0 1 8.5 2H12v7H8.5A3.5 3.5 0 0 1 5 5.5z"/><path d="M12 2h3.5a3.5 3.5 0 1 1 0 7H12V2z"/><path d="M12 12.5a3.5 3.5 0 1 1 7 0 3.5 3.5 0 1 1-7 0z"/><path d="M5 19.5A3.5 3.5 0 0 1 8.5 16H12v3.5a3.5 3.5 0 1 1-7 0z"/><path d="M5 12.5A3.5 3.5 0 0 1 8.5 9H12v7H8.5A3.5 3.5 0 0 1 5 12.5z"/></svg>
<span class="grow">
<span class="block text-lg font-semibold text-blue-500">Advanced tools</span>
<span class="block mt-1 text-neutral-200">Use Preline's automated libraries to manage your business.</span>
</span>
</span>
</button>
<button type="button" class="hs-tab-active:bg-neutral-700 hs-tab-active:shadow-md text-start hover:bg-neutral-700 focus:bg-neutral-700 p-4 md:p-5 rounded-xl" id="tabs-with-card-item-2" aria-selected="false" data-hs-tab="#tabs-with-card-2" aria-controls="tabs-with-card-2" role="tab">
<span class="flex gap-x-6">
<svg class="shrink-0 mt-2 size-6 md:size-7 text-blue-500" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m12 14 4-4"/><path d="M3.34 19a10 10 0 1 1 17.32 0"/></svg>
<span class="grow">
<span class="block text-lg font-semibold text-blue-500">Smart dashboards</span>
<span class="block mt-1 text-neutral-200">Quickly use Preline sample components.</span>
</span>
</span>
</button>
<button type="button" class="hs-tab-active:bg-neutral-700 hs-tab-active:shadow-md text-start hover:bg-neutral-700 focus:bg-neutral-700 p-4 md:p-5 rounded-xl" id="tabs-with-card-item-3" aria-selected="false" data-hs-tab="#tabs-with-card-3" aria-controls="tabs-with-card-3" role="tab">
<span class="flex gap-x-6">
<svg class="shrink-0 mt-2 size-6 md:size-7 text-blue-500" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z"/><path d="M5 3v4"/><path d="M19 17v4"/><path d="M3 5h4"/><path d="M17 19h4"/></svg>
<span class="grow">
<span class="block text-lg font-semibold text-blue-500">Powerful features</span>
<span class="block mt-1 text-neutral-200">Save time with Preline's modern designs.</span>
</span>
</span>
</button>
</nav>
</div>
<!-- End Col -->
<div class="lg:col-span-6">
<div class="relative">
<!-- Tab Content -->
<div>
<div id="tabs-with-card-1" role="tabpanel" aria-labelledby="tabs-with-card-item-1">
<img class="shadow-xl shadow-gray-900/20 rounded-xl" src="https://images.unsplash.com/photo-1605629921711-2f6b00c6bbf4?ixlib=rb-4.0.3&auto=format&fit=crop&w=560&h=720&q=80" alt="Features Image">
</div>
<div id="tabs-with-card-2" class="hidden" role="tabpanel" aria-labelledby="tabs-with-card-item-2">
<img class="shadow-xl shadow-gray-900/20 rounded-xl" src="https://images.unsplash.com/photo-1665686306574-1ace09918530?ixlib=rb-4.0.3&auto=format&fit=crop&w=560&h=720&q=80" alt="Features Image">
</div>
<div id="tabs-with-card-3" class="hidden" role="tabpanel" aria-labelledby="tabs-with-card-item-3">
<img class="shadow-xl shadow-gray-900/20 rounded-xl" src="https://images.unsplash.com/photo-1598929213452-52d72f63e307?ixlib=rb-4.0.3&auto=format&fit=crop&w=560&h=720&q=80" alt="Features Image">
</div>
</div>
<!-- End Tab Content -->
</div>
</div>
<!-- End Col -->
</div>
<!-- End Grid -->
<!-- Background Color -->
<div class="absolute inset-0 bg-neutral-800 rounded-xl"></div>
</div>
</div>
<!-- End Features -->
</div>
</template>
\ No newline at end of file
......@@ -79,7 +79,7 @@
const auth = getAuth();
await signInWithEmailAndPassword(auth, email.value, password.value);
console.log('Successfully registered!');
router.push('/feed');
router.push('/films');
} catch (error) {
console.error(error);
alert(error.message);
......@@ -95,7 +95,7 @@
const provider = new GoogleAuthProvider();
await signInWithPopup(auth, provider);
console.log('Successfully signed in with Google!');
router.push('/feed');
router.push('/films');
} catch (error) {
console.error(error);
alert(error.message);
......
......@@ -95,7 +95,7 @@ loading.value = true;
try {
const auth = getAuth();
await createUserWithEmailAndPassword(auth, email.value, password.value);
router.push('/feed');
router.push('/films');
} catch (error) {
alert(error.message);
} finally {
......
<template>Watchlist</template>
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment