Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions resources/css/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,24 @@
@custom-variant dark (&:where(.dark, .dark *));

@layer base {
html,
body {
font-stretch: 96%;
@apply transition-colors duration-300;
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* IE and Edge */
}

/* Hide scrollbar for Chrome, Safari and Opera */
*::-webkit-scrollbar {
display: none;
width: 0 !important;
height: 0 !important;
}

* {
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* IE and Edge */
}
}

Expand Down
4 changes: 2 additions & 2 deletions resources/js/components/AppLogo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ const logoHref = computed(() => {
const pref = localStorage.getItem('preferred_course');

if (pref === 'ssc') {
return '/ssc';
}
return '/ssc';
}
} catch {
// ignore
}
Expand Down
17 changes: 12 additions & 5 deletions resources/js/components/CourseSwitcher.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ const setCoursePreference = (course: 'hsc' | 'ssc') => {
class="mb-6 rounded-xl border border-slate-200 bg-white p-3.5 shadow-xs transition-all sm:p-5 dark:border-gray-700 dark:bg-gray-900"
>
<div
class="flex items-center justify-between gap-3 cursor-pointer sm:cursor-default"
class="flex cursor-pointer items-center justify-between gap-3 sm:cursor-default"
@click="toggleMobileExpand"
>
<!-- Large Browsing Indicator -->
<div class="flex items-center gap-3 min-w-0">
<div class="flex min-w-0 items-center gap-3">
<span
class="inline-flex shrink-0 items-center justify-center rounded-lg px-2.5 py-1 text-lg font-black text-white shadow-xs sm:px-3.5 sm:py-1.5 sm:text-2xl"
:class="isSsc ? 'bg-emerald-600' : 'bg-indigo-600'"
Expand All @@ -45,7 +45,7 @@ const setCoursePreference = (course: 'hsc' | 'ssc') => {
Active Repository
</span>
<p
class="truncate text-xs leading-snug font-extrabold text-slate-900 sm:text-base sm:whitespace-normal dark:text-gray-100"
class="text-xs leading-snug font-extrabold text-slate-900 sm:text-base dark:text-gray-100"
>
আপনি <span>{{ isSsc ? 'SSC' : 'HSC' }}</span> এর
কন্টেন্টগুলো দেখছেন
Expand All @@ -60,7 +60,10 @@ const setCoursePreference = (course: 'hsc' | 'ssc') => {
>
<ChevronDown
class="h-4 w-4 transition-transform duration-200"
:class="{ 'rotate-180 text-slate-700 dark:text-gray-200': isMobileExpanded }"
:class="{
'rotate-180 text-slate-700 dark:text-gray-200':
isMobileExpanded,
}"
/>
</div>

Expand Down Expand Up @@ -89,7 +92,11 @@ const setCoursePreference = (course: 'hsc' | 'ssc') => {
<!-- Mobile Expandable Switch Action Area (Glitch-Free CSS Grid Accordion) -->
<div
class="grid transition-all duration-200 ease-in-out sm:hidden"
:class="isMobileExpanded ? 'grid-rows-[1fr] opacity-100 mt-3 pt-3 border-t border-slate-100 dark:border-gray-800' : 'grid-rows-[0fr] opacity-0'"
:class="
isMobileExpanded
? 'mt-3 grid-rows-[1fr] border-t border-slate-100 pt-3 opacity-100 dark:border-gray-800'
: 'grid-rows-[0fr] opacity-0'
"
>
<div class="overflow-hidden">
<Link
Expand Down
7 changes: 1 addition & 6 deletions resources/js/components/FloatingShareBar.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
<script setup lang="ts">
import { usePage } from '@inertiajs/vue3';
import {
Share2,
Check,
Loader2,
Link as LinkIcon,
} from 'lucide-vue-next';
import { Share2, Check, Loader2, Link as LinkIcon } from 'lucide-vue-next';
import { computed, ref, onMounted, onBeforeUnmount } from 'vue';
import AuthModal from './AuthModal.vue';

Expand Down
12 changes: 9 additions & 3 deletions resources/js/components/Footer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -238,14 +238,18 @@ const isFullFooter = computed(() => {
v-if="!isFullFooter"
class="mt-auto border-t border-slate-200/70 bg-white/80 pt-8 pb-6 backdrop-blur-md md:hidden dark:border-gray-800/70 dark:bg-gray-950/80"
>
<div class="mx-auto flex max-w-7xl flex-col items-center gap-3.5 px-4 text-center">
<div
class="mx-auto flex max-w-7xl flex-col items-center gap-3.5 px-4 text-center"
>
<!-- App Logo with top breathing room -->
<div class="pt-1">
<AppLogo />
</div>

<!-- Essential Links -->
<div class="flex flex-wrap items-center justify-center gap-x-4 gap-y-1.5 text-xs font-medium text-slate-600 dark:text-gray-400">
<div
class="flex flex-wrap items-center justify-center gap-x-4 gap-y-1.5 text-xs font-medium text-slate-600 dark:text-gray-400"
>
<Link
href="/about-us"
class="transition hover:text-indigo-600 dark:hover:text-indigo-400"
Expand Down Expand Up @@ -273,7 +277,9 @@ const isFullFooter = computed(() => {
</div>

<!-- Copyright at the bottom -->
<p class="pt-1.5 text-[11px] font-medium text-slate-400 dark:text-gray-500">
<p
class="pt-1.5 text-[11px] font-medium text-slate-400 dark:text-gray-500"
>
&copy; 2026 HSCStack
</p>
</div>
Expand Down
102 changes: 74 additions & 28 deletions resources/js/components/NavBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,14 @@ import {
HeartHandshake,
Search,
} from 'lucide-vue-next';
import { computed, ref, onMounted, onBeforeUnmount, watch, nextTick } from 'vue';
import {
computed,
ref,
onMounted,
onBeforeUnmount,
watch,
nextTick,
} from 'vue';
import { globalSearchQuery } from '@/lib/searchStore';
import { useDarkMode } from '@/lib/useDarkMode';
import AppLogo from './AppLogo.vue';
Expand Down Expand Up @@ -63,7 +70,8 @@ const searchInputRef = ref<HTMLInputElement | null>(null);

const triggerSearch = () => {
if (!user.value) {
authModalMessage.value = 'অনুগ্রহ করে বিষয় ও কনটেন্ট সার্চ করতে প্রথমে লগইন করুন।';
authModalMessage.value =
'অনুগ্রহ করে বিষয় ও কনটেন্ট সার্চ করতে প্রথমে লগইন করুন।';
showAuthModal.value = true;

return;
Expand All @@ -90,8 +98,8 @@ const homeHref = computed(() => {
const pref = localStorage.getItem('preferred_course');

if (pref === 'ssc') {
return '/ssc';
}
return '/ssc';
}
} catch {
// ignore
}
Expand Down Expand Up @@ -194,7 +202,7 @@ onBeforeUnmount(() => {
<div
v-if="searchActive"
ref="searchContainerRef"
class="flex h-full w-full items-center gap-3 animate-in fade-in duration-150"
class="animate-in fade-in flex h-full w-full items-center gap-3 duration-150"
>
<div class="relative flex-1">
<input
Expand All @@ -205,10 +213,12 @@ onBeforeUnmount(() => {
class="w-full appearance-none rounded-xl border border-slate-200 bg-slate-50 py-2.5 pr-20 pl-10 text-sm font-semibold text-slate-800 placeholder:text-slate-400 focus:border-indigo-500 focus:bg-white focus:outline-none dark:border-gray-700 dark:bg-gray-900 dark:text-gray-100 dark:placeholder:text-gray-500 dark:focus:border-indigo-400 dark:focus:bg-gray-900"
/>
<Search
class="pointer-events-none absolute top-1/2 -translate-y-1/2 left-3 h-4 w-4 text-slate-400"
class="pointer-events-none absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-slate-400"
/>

<div class="absolute right-2 top-1/2 -translate-y-1/2 flex items-center gap-1.5">
<div
class="absolute top-1/2 right-2 flex -translate-y-1/2 items-center gap-1.5"
>
<button
v-if="globalSearchQuery"
@click="clearSearch"
Expand Down Expand Up @@ -250,7 +260,7 @@ onBeforeUnmount(() => {

<!-- Center/Desktop Navigation (md and up) - Perfectly centered -->
<nav
class="hidden md:flex absolute left-1/2 -translate-x-1/2 items-center gap-6"
class="absolute left-1/2 hidden -translate-x-1/2 items-center gap-6 md:flex"
>
<Link
:href="homeHref"
Expand Down Expand Up @@ -388,7 +398,9 @@ onBeforeUnmount(() => {
class="flex items-center gap-2.5 rounded-xl px-3 py-2 text-xs font-semibold text-slate-700 transition-colors hover:bg-slate-50 hover:text-slate-900 dark:text-gray-300 dark:hover:bg-gray-800 dark:hover:text-white"
@click="closeDropdown"
>
<User class="h-3.5 w-3.5 text-slate-400" />
<User
class="h-3.5 w-3.5 text-slate-400"
/>
Profile
</Link>

Expand All @@ -399,7 +411,9 @@ onBeforeUnmount(() => {
@click="closeDropdown"
>
<component
:is="isAdmin ? Home : LayoutDashboard"
:is="
isAdmin ? Home : LayoutDashboard
"
class="h-3.5 w-3.5 text-slate-400"
/>
{{ isAdmin ? 'Home' : 'Staff Panel' }}
Expand Down Expand Up @@ -488,7 +502,9 @@ onBeforeUnmount(() => {
class="relative flex h-full w-full max-w-xs flex-col justify-between border-l border-slate-200/80 bg-white/95 shadow-2xl backdrop-blur-2xl dark:border-gray-800 dark:bg-gray-950/95"
>
<!-- Top Header in Drawer -->
<div class="flex items-center justify-between border-b border-slate-100 p-4 dark:border-gray-800/80">
<div
class="flex items-center justify-between border-b border-slate-100 p-4 dark:border-gray-800/80"
>
<AppLogo />
<button
@click="closeMobileMenu"
Expand All @@ -500,11 +516,15 @@ onBeforeUnmount(() => {
</div>

<!-- Scrollable Drawer Body -->
<div class="flex-1 overflow-y-auto px-4 py-4 space-y-6">
<div class="flex-1 space-y-6 overflow-y-auto px-4 py-4">
<!-- User Card or Guest Login CTA -->
<div v-if="user">
<Link
:href="user.username ? `/u/${user.username}` : '/profile'"
:href="
user.username
? `/u/${user.username}`
: '/profile'
"
@click="closeMobileMenu"
class="flex items-center gap-3 rounded-2xl border border-slate-200/80 bg-slate-50/80 p-3 transition hover:border-slate-300 hover:bg-slate-100 dark:border-gray-800 dark:bg-gray-900/60 dark:hover:border-gray-700 dark:hover:bg-gray-900"
>
Expand All @@ -521,10 +541,14 @@ onBeforeUnmount(() => {
{{ user.name.charAt(0).toUpperCase() }}
</div>
<div class="min-w-0 flex-1">
<p class="truncate text-xs font-bold text-slate-900 dark:text-gray-100">
<p
class="truncate text-xs font-bold text-slate-900 dark:text-gray-100"
>
{{ user.name }}
</p>
<p class="truncate text-[11px] text-slate-400 dark:text-gray-500">
<p
class="truncate text-[11px] text-slate-400 dark:text-gray-500"
>
{{ user.email }}
</p>
</div>
Expand All @@ -544,7 +568,9 @@ onBeforeUnmount(() => {

<!-- Main Exploration Navigation -->
<div>
<p class="mb-2 px-2 text-[10px] font-bold tracking-wider text-slate-400 uppercase dark:text-gray-500">
<p
class="mb-2 px-2 text-[10px] font-bold tracking-wider text-slate-400 uppercase dark:text-gray-500"
>
Explore
</p>
<div class="space-y-1">
Expand Down Expand Up @@ -580,12 +606,18 @@ onBeforeUnmount(() => {

<!-- Account / Admin Links (if logged in, placed above platform) -->
<div v-if="user">
<p class="mb-2 px-2 text-[10px] font-bold tracking-wider text-slate-400 uppercase dark:text-gray-500">
<p
class="mb-2 px-2 text-[10px] font-bold tracking-wider text-slate-400 uppercase dark:text-gray-500"
>
Account
</p>
<div class="space-y-1">
<Link
:href="user.username ? `/u/${user.username}` : '/profile'"
:href="
user.username
? `/u/${user.username}`
: '/profile'
"
@click="closeMobileMenu"
class="flex items-center gap-3 rounded-xl px-3 py-2 text-xs font-semibold text-slate-600 hover:bg-slate-100/70 hover:text-slate-900 dark:text-gray-400 dark:hover:bg-gray-900/60 dark:hover:text-gray-200"
>
Expand All @@ -600,17 +632,23 @@ onBeforeUnmount(() => {
class="flex items-center gap-3 rounded-xl px-3 py-2 text-xs font-semibold text-slate-600 hover:bg-slate-100/70 hover:text-slate-900 dark:text-gray-400 dark:hover:bg-gray-900/60 dark:hover:text-gray-200"
>
<component
:is="isAdmin ? Home : LayoutDashboard"
:is="
isAdmin ? Home : LayoutDashboard
"
class="h-4 w-4 text-slate-400"
/>
<span>{{ isAdmin ? 'Home' : 'Staff Panel' }}</span>
<span>{{
isAdmin ? 'Home' : 'Staff Panel'
}}</span>
</Link>
</div>
</div>

<!-- Platform Links -->
<div>
<p class="mb-2 px-2 text-[10px] font-bold tracking-wider text-slate-400 uppercase dark:text-gray-500">
<p
class="mb-2 px-2 text-[10px] font-bold tracking-wider text-slate-400 uppercase dark:text-gray-500"
>
Platform
</p>
<div class="space-y-1">
Expand All @@ -619,7 +657,9 @@ onBeforeUnmount(() => {
@click="closeMobileMenu"
class="flex items-center gap-3 rounded-xl px-3 py-2 text-xs font-semibold text-slate-600 hover:bg-slate-100/70 hover:text-slate-900 dark:text-gray-400 dark:hover:bg-gray-900/60 dark:hover:text-gray-200"
>
<Sparkles class="h-4 w-4 text-amber-500" />
<Sparkles
class="h-4 w-4 text-amber-500"
/>
<span>AI Assistant</span>
</Link>

Expand All @@ -646,21 +686,29 @@ onBeforeUnmount(() => {
@click="closeMobileMenu"
class="flex items-center gap-3 rounded-xl px-3 py-2 text-xs font-semibold text-slate-600 hover:bg-slate-100/70 hover:text-slate-900 dark:text-gray-400 dark:hover:bg-gray-900/60 dark:hover:text-gray-200"
>
<HeartHandshake class="h-4 w-4 text-rose-500" />
<HeartHandshake
class="h-4 w-4 text-rose-500"
/>
<span>Support HSCStack</span>
</Link>
</div>
</div>
</div>

<!-- Footer Actions in Drawer -->
<div class="border-t border-slate-100 p-4 dark:border-gray-800/80">
<div
class="border-t border-slate-100 p-4 dark:border-gray-800/80"
>
<!-- Theme Preference Switcher -->
<div>
<p class="mb-2 text-[10px] font-bold tracking-wider text-slate-400 uppercase dark:text-gray-500">
<p
class="mb-2 text-[10px] font-bold tracking-wider text-slate-400 uppercase dark:text-gray-500"
>
Appearance
</p>
<div class="grid grid-cols-3 gap-1 rounded-xl bg-slate-100 p-1 dark:bg-gray-900">
<div
class="grid grid-cols-3 gap-1 rounded-xl bg-slate-100 p-1 dark:bg-gray-900"
>
<button
type="button"
@click="theme = 'light'"
Expand Down Expand Up @@ -709,5 +757,3 @@ onBeforeUnmount(() => {
</Teleport>
</nav>
</template>


1 change: 0 additions & 1 deletion resources/js/components/admin/DesktopSidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,5 @@ const handleClearCache = () => {
Clear cache
</span>
</button>

</div>
</template>
Loading