Skip to content

Commit

Permalink
Merge pull request #24 from isd-sgcu/feat/annoucePage
Browse files Browse the repository at this point in the history
Feat/annouce page
  • Loading branch information
Chulinuwu authored Oct 17, 2024
2 parents c75950e + 88de975 commit 207028a
Show file tree
Hide file tree
Showing 8 changed files with 400 additions and 0 deletions.
Binary file added src/lib/assets/images/picslide1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/lib/assets/images/picslide2.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/lib/assets/images/picslide3.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/lib/assets/images/picslide4.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
91 changes: 91 additions & 0 deletions src/lib/mock/announcement.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { DocumentType, Role, type Document, type User } from '$lib/types';
import dayjs from 'dayjs';
import buddhistEra from 'dayjs/plugin/buddhistEra';

dayjs.extend(buddhistEra);
export // * mock data
const created_at_1 = '2022-01-01';
const created_at_2 = '2023-01-01';
const created_at_3 = '2024-01-01';
const created_at_4 = '2025-01-01';
const updated_at = '2030-02-01';

const sgcu_admin: User = {
id: '6000000000',
first_name: 'Admin',
last_name: 'Admin',
role: Role.SGCU_SUPERADMIN,
created_at: created_at_1,
updated_at
};
const sccu_admin: User = {
id: '6000000001',
first_name: 'Admin',
last_name: 'Admin',
role: Role.SCCU_SUPERADMIN,
created_at: created_at_2,
updated_at
};

export const announcements: Document[] = [
{
id: 'DOC-09649054',
title: 'เอกสารลับจากดัมเบิลดอร์',
content: 'เนื้อหาของเอกสารลับจากดัมเบิลดอร์',
user_id: sgcu_admin.id,
type_id: DocumentType.ANNOUNCEMENT,
created_at: created_at_3,
updated_at,
author: sgcu_admin
},
{
id: 'DOC-09649055',
title: 'ประกาศรับสมัครคณะกรรมาธิการวิสามัญพิจารณางบประมาณสโมสรนิสิต 00',
content: 'เนื้อหาของประกาศรับสมัครคณะกรรมาธิการวิสามัญพิจารณางบประมาณสโมสรนิสิต',
user_id: sccu_admin.id,
type_id: DocumentType.ANNOUNCEMENT,
created_at: created_at_4,
updated_at,
author: sccu_admin
},
{
id: 'DOC-09649056',
title: 'ประกาศรับสมัครคณะกรรมาธิการวิสามัญพิจารณางบประมาณสโมสรนิสิต 01',
content: 'เนื้อหาของประกาศรับสมัครคณะกรรมาธิการวิสามัญพิจารณางบประมาณสโมสรนิสิต',
user_id: sgcu_admin.id,
type_id: DocumentType.ANNOUNCEMENT,
created_at: created_at_4,
updated_at,
author: sgcu_admin
},
{
id: 'DOC-09649056',
title: 'ประกาศรับสมัครคณะกรรมาธิการวิสามัญพิจารณางบประมาณสโมสรนิสิต 02',
content: 'เนื้อหาของประกาศรับสมัครคณะกรรมาธิการวิสามัญพิจารณางบประมาณสโมสรนิสิต',
user_id: sccu_admin.id,
type_id: DocumentType.BUDGET,
created_at: created_at_1,
updated_at,
author: sccu_admin
},
{
id: 'DOC-09649058',
title: 'ประกาศรับสมัครคณะกรรมาธิการวิสามัญพิจารณางบประมาณสโมสรนิสิต 03',
content: 'เนื้อหาของประกาศรับสมัครคณะกรรมาธิการวิสามัญพิจารณางบประมาณสโมสรนิสิต',
user_id: sccu_admin.id,
type_id: DocumentType.STATISTIC,
created_at: created_at_1,
updated_at,
author: sgcu_admin
},
{
id: 'DOC-09649060',
title: 'ประกาศรับสมัครคณะกรรมาธิการวิสามัญพิจารณางบประมาณสโมสรนิสิต 04',
content: 'เนื้อหาของประกาศรับสมัครคณะกรรมาธิการวิสามัญพิจารณางบประมาณสโมสรนิสิต',
user_id: sccu_admin.id,
type_id: DocumentType.STATISTIC,
created_at: created_at_1,
updated_at,
author: sgcu_admin
}
];
254 changes: 254 additions & 0 deletions src/routes/announcement/+page.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@
<script lang="ts">
import { cn } from '$lib/utils';
import {
faCircleArrowLeft,
faChevronRight,
faChevronLeft
} from '@fortawesome/free-solid-svg-icons';
import { typography } from '../../styles/tailwind/typography';
import Fa from 'svelte-fa';
import TabsRoot from '$lib/components/Tabs/TabsRoot.svelte';
import TabsList from '$lib/components/Tabs/TabsList.svelte';
import TabsTrigger from '$lib/components/Tabs/TabsTrigger.svelte';
import TabsContent from '$lib/components/Tabs/TabsContent.svelte';
import MaxWidthWrapper from '$lib/components/MaxWidthWrapper.svelte';
import pic1 from './../../lib/assets/images/picslide1.jpg';
import pic2 from './../../lib/assets/images/picslide2.jpg';
import pic3 from './../../lib/assets/images/picslide3.jpg';
import pic4 from './../../lib/assets/images/picslide4.jpg';
import SearchBar from '$lib/components/SearchBar.svelte';
import Dropdown from '$lib/components/Dropdown/Dropdown.svelte';
import AnnounceList from './AnnounceList.svelte';
import { Role } from '$lib/types/role';
import type { Document as CustomDocument } from '$lib/types/document';
import Pagination from '$lib/components/Pagination/Pagination.svelte';
export let data;
const { announcements } = data;
let PaginationMockitem: string[] = [
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'10',
'11',
'12',
'13',
'14',
'15',
'16',
'17',
'18',
'19',
'20',
'21',
'22',
'23',
'24',
'25',
'26',
'27',
'28',
'29',
'30'
];
export let image = [pic1, pic2, pic3, pic4];
let searchValue = '';
let dropdownValue = 'All';
let currentIndex = 0;
let years = Array.from(
new Set(announcements.map((doc) => new Date(doc.created_at).getFullYear()))
)
.sort((a, b) => b - a)
.map(String);
function handleLeftClick() {
currentIndex = (currentIndex - 1) % image.length;
if (currentIndex == -1) {
currentIndex = image.length - 1;
}
scrollToImage();
}
function handleRightClick() {
currentIndex = (currentIndex + 1) % image.length;
scrollToImage();
}
function scrollToImage() {
const container = document.querySelector('.image-container');
if (container) {
const imageWidth = container.clientWidth;
container.scrollTo({
left: imageWidth * currentIndex,
behavior: 'smooth'
});
}
}
let paginatedAll: CustomDocument[] = [];
let paginatedSGCU: CustomDocument[] = [];
let paginatedSCCU: CustomDocument[] = [];
let currentPages = {
all: 1,
sgcu: 1,
sccu: 1
};
const documentsPerPage = 10;
const filteredDocuments = (tab: 'all' | 'sgcu' | 'sccu') => {
let filteredDocs = announcements;
const filterRole = (authorRole: string, docRole: Role) => {
return authorRole.split('_')[0] === docRole.split('_')[0];
};
if (searchValue) {
filteredDocs = filteredDocs.filter((doc) =>
doc.title.toLowerCase().includes(searchValue.toLowerCase())
);
}
if (dropdownValue && dropdownValue !== 'All') {
filteredDocs = filteredDocs.filter((doc) => {
const year = new Date(doc.created_at).getFullYear().toString();
return year === dropdownValue;
});
}
switch (tab) {
case 'sgcu':
filteredDocs = filteredDocs.filter((doc) => filterRole(doc.author.role, Role.SGCU_ADMIN));
break;
case 'sccu':
filteredDocs = filteredDocs.filter((doc) => filterRole(doc.author.role, Role.SCCU_ADMIN));
break;
}
return filteredDocs;
};
function paginate(docs: CustomDocument[], currentPage: number, documentsPerPage: number) {
const start = (currentPage - 1) * documentsPerPage;
const end = currentPage * documentsPerPage;
return docs.slice(start, end);
}
$: totalPages = {
all: Math.ceil(filteredDocuments('all').length / documentsPerPage),
sgcu: Math.ceil(filteredDocuments('sgcu').length / documentsPerPage),
sccu: Math.ceil(filteredDocuments('sccu').length / documentsPerPage)
};
$: {
paginatedAll = paginate(filteredDocuments('all'), currentPages.all, documentsPerPage);
paginatedSGCU = paginate(filteredDocuments('sgcu'), currentPages.sgcu, documentsPerPage);
paginatedSCCU = paginate(filteredDocuments('sccu'), currentPages.sccu, documentsPerPage);
searchValue = searchValue;
dropdownValue = dropdownValue;
}
function changePage(tab: 'all' | 'sgcu' | 'sccu', direction: 'next' | 'prev') {
const page = currentPages[tab];
const totalPage = totalPages[tab];
if (direction === 'next' && page < totalPage) {
currentPages[tab]++;
} else if (direction === 'prev' && page > 1) {
currentPages[tab]--;
}
}
</script>

<div>
<div class="relative flex w-full h-[500px]">
<button
class="absolute left-5 top-1/2 transform -translate-y-1/2 z-10 cursor-pointe transition-all"
on:click={handleLeftClick}
>
<Fa icon={faChevronLeft} class="text-white scale-150" />
</button>
<div class="relative w-full h-[500px] flex overflow-hidden image-container snap-x">
{#each image as img}
<div class="w-full h-full flex-shrink-0 snap-center">
<img src={img} alt="pic" class="w-full h-full object-cover" />
</div>
{/each}
</div>
<button
class="absolute right-5 top-1/2 transform -translate-y-1/2 z-10 cursor-pointer transition-all"
on:click={handleRightClick}
>
<Fa icon={faChevronRight} class="text-white scale-150" />
</button>
</div>

<MaxWidthWrapper class="my-10 space-y-12">
<div class="flex flex-col gap-3 items-start">
<div class="flex items-center gap-4">
<button on:click={() => history.back()} class="lg:relative -left-52 scale-150">
<Fa icon={faCircleArrowLeft} size="lg" />
</button>
<h1 class={cn(typography({ variant: 'heading3' }), 'md:text-5xl lg:order-first')}>
ประกาศ
</h1>
</div>
<p class="text-sucu-gray lg:w-full">
เอกสารทั้งหมดในนามสโมสรนิสิตจุฬาฯ อบจ. และสภานิสิตจุฬาฯ ซึ่งเปิดเผยให้นิสิตได้อ่านโดยทั่วกัน
</p>
</div>

<SearchBar bind:value={searchValue} />

<TabsRoot defaultActiveTab="all">
<TabsList>
<TabsTrigger value="all">ทั้งหมด</TabsTrigger>
<TabsTrigger value="sgcu">อบจ.</TabsTrigger>
<TabsTrigger value="sccu">สภานิสิต</TabsTrigger>
</TabsList>

<Dropdown
items={['All', ...years]}
bind:currentChoice={dropdownValue}
outerClass="w-64 my-12"
/>

<TabsContent value="all" class="space-y-2">
<AnnounceList
currentPage={currentPages.all}
changePage={(variant, direction) => changePage(variant, direction)}
documents={paginatedAll}
totalPages={totalPages.all}
variantKey="all"
/>
</TabsContent>

<TabsContent value="sgcu" class="space-y-2">
<AnnounceList
currentPage={currentPages.sgcu}
changePage={(variant, direction) => changePage(variant, direction)}
documents={paginatedSGCU}
totalPages={totalPages.sgcu}
variantKey="sgcu"
/>
</TabsContent>

<TabsContent value="sccu" class="space-y-2">
<AnnounceList
currentPage={currentPages.sccu}
changePage={(variant, direction) => changePage(variant, direction)}
documents={paginatedSCCU}
totalPages={totalPages.sccu}
variantKey="sccu"
/>
</TabsContent>
</TabsRoot>
</MaxWidthWrapper>

<Pagination Arrayitem={PaginationMockitem} />
</div>
9 changes: 9 additions & 0 deletions src/routes/announcement/+page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type { PageLoad } from './$types';
import 'dayjs/locale/th';
import { announcements } from '$lib/mock/announcement';

export const load: PageLoad = async () => {
return {
announcements
};
};
Loading

0 comments on commit 207028a

Please sign in to comment.