Skip to content

Commit

Permalink
Merge pull request #30 from isd-sgcu/macgeargear/sucu-72-stat-page
Browse files Browse the repository at this point in the history
Macgeargear/sucu 72 stat page
  • Loading branch information
punchanabu authored Nov 5, 2024
2 parents 330a6f3 + 2a54da2 commit 35a17ba
Show file tree
Hide file tree
Showing 8 changed files with 2,500 additions and 1,726 deletions.
3,929 changes: 2,205 additions & 1,724 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/lib/components/Navbar.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
const navItems = [
{ name: 'ประกาศ', href: '/' },
{ name: 'เอกสาร', href: '/document' },
{ name: 'งบประมาณและสถิติ', href: '/' },
{ name: 'งบประมาณและสถิติ', href: '/stat' },
{ name: 'สโมสรนิสิตฯ', href: '/' }
];
</script>
Expand Down
22 changes: 21 additions & 1 deletion src/lib/mock/document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export const documents: Document[] = [
type_id: DocumentType.STATISTIC,
created_at: created_at_1,
updated_at,
author: sgcu_admin
author: sccu_admin
},
{
id: 'DOC-09649060',
Expand All @@ -86,6 +86,26 @@ export const documents: Document[] = [
type_id: DocumentType.STATISTIC,
created_at: created_at_1,
updated_at,
author: sccu_admin
},
{
id: 'DOC-09649061',
title: 'ประกาศรับสมัครคณะกรรมาธิการวิสามัญพิจารณางบประมาณสโมสรนิสิต 05',
content: 'เนื้อหาของประกาศรับสมัครคณะกรรมาธิการวิสามัญพิจารณางบประมาณสโมสรนิสิต',
user_id: sgcu_admin.id,
type_id: DocumentType.STATISTIC,
created_at: created_at_2,
updated_at,
author: sgcu_admin
},
{
id: 'DOC-09649062',
title: 'ประกาศรับสมัครคณะกรรมาธิการวิสามัญพิจารณางบประมาณสโมสรนิสิต 06',
content: 'เนื้อหาของประกาศรับสมัครคณะกรรมาธิการวิสามัญพิจารณางบประมาณสโมสรนิสิต',
user_id: sgcu_admin.id,
type_id: DocumentType.STATISTIC,
created_at: created_at_2,
updated_at,
author: sgcu_admin
}
];
157 changes: 157 additions & 0 deletions src/routes/stat/+page.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
<script lang="ts">
import MaxWidthWrapper from '$lib/components/MaxWidthWrapper.svelte';
import { cn } from '$lib/utils';
import { faCircleArrowLeft } from '@fortawesome/free-solid-svg-icons';
import Fa from 'svelte-fa';
import { typography } from '../../styles/tailwind/typography';
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 Dropdown from '$lib/components/Dropdown/Dropdown.svelte';
import TabsContent from '$lib/components/Tabs/TabsContent.svelte';
import StatList from './StatList.svelte';
import { Role, type Document } from '$lib/types';
export let data;
const { documents } = data;
let searchValue = '';
let dropdownValue = 'All';
let years = Array.from(new Set(documents.map((doc) => new Date(doc.created_at).getFullYear())))
.sort((a, b) => b - a)
.map(String);
let paginatedAll: Document[] = [];
let paginatedSGCU: Document[] = [];
let paginatedSCCU: Document[] = [];
let currentPages = {
all: 1,
sgcu: 1,
sccu: 1
};
const documentsPerPage = 3;
$: 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;
}
const filteredDocuments = (tab: 'all' | 'sgcu' | 'sccu') => {
let filteredDocs = documents;
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: Document[], currentPage: number, documentsPerPage: number) {
const start = (currentPage - 1) * documentsPerPage;
const end = currentPage * documentsPerPage;
return docs.slice(start, end);
}
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>

<MaxWidthWrapper class="mt-10 space-y-12">
<div class="flex flex-col gap-3 items-start">
<button on:click={() => history.back()} class="lg:relative -left-14 top-12">
<Fa icon={faCircleArrowLeft} size="lg" />
</button>
<div class="flex items-center gap-4">
<h1 class={cn(typography({ variant: 'heading3' }), 'md:text-5xl lg:order-first')}>
งบประมาณและสถิติ
</h1>
</div>
<p class="lg:w-full">
เปิดเผยข้อมูลทั้งสถิติการลงคะแนนเสียงในการประชุมสภา และงบประมาณในโครงการต่าง ๆ
ให้นิสิตได้เข้าตรวจสอบ วี้หว่อ ๆๆๆ
</p>
</div>

<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-4 p-0">
<StatList
currentPage={currentPages.all}
changePage={(variant, direction) => changePage(variant, direction)}
documents={paginatedAll}
totalPages={totalPages.all}
variantKey="all"
/>
</TabsContent>

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

<TabsContent value="sccu" class="space-y-4 p-0">
<StatList
currentPage={currentPages.sccu}
changePage={(variant, direction) => changePage(variant, direction)}
documents={paginatedSCCU}
totalPages={totalPages.sccu}
variantKey="sccu"
/>
</TabsContent>
</TabsRoot>
</MaxWidthWrapper>
9 changes: 9 additions & 0 deletions src/routes/stat/+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 { documents } from '$lib/mock/document';

export const load: PageLoad = async () => {
return {
documents: documents.filter((doc) => doc.type_id === 'STATISTIC' || doc.type_id === 'BUDGET')
};
};
46 changes: 46 additions & 0 deletions src/routes/stat/StatList.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<script lang="ts">
import Button from '$lib/components/Button.svelte';
import StatisticCard from '$lib/components/StatisticCard/StatisticCard.svelte';
import type { Document } from '$lib/types';
import { faChevronLeft, faChevronRight } from '@fortawesome/free-solid-svg-icons';
import Fa from 'svelte-fa';
export let documents: Document[] = [];
export let currentPage: number = 1;
export let totalPages: number = 1;
export let changePage: (variant: 'all' | 'sgcu' | 'sccu', direction: 'next' | 'prev') => void;
export let variantKey: 'all' | 'sgcu' | 'sccu' = 'all';
</script>

{#if documents.length === 0}
<p>No documents available.</p>
{:else}
{#each documents as document}
<StatisticCard
title={document.title}
createAt={document.created_at}
infoType={document.type_id}
organization={document.author.role}
hrefUrl={`/stat/${document.id}`}
/>
{/each}
{/if}

<div class="flex items-center justify-end gap-2 mt-4">
<Button
variant="outline"
size="sm"
on:click={() => changePage(variantKey, 'prev')}
disabled={currentPage === 1}
>
<Fa icon={faChevronLeft} />
</Button>
<Button
variant="outline"
size="sm"
on:click={() => changePage(variantKey, 'next')}
disabled={currentPage === totalPages}
>
<Fa icon={faChevronRight} />
</Button>
</div>
53 changes: 53 additions & 0 deletions src/routes/stat/[id]/+page.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<script lang="ts">
import MaxWidthWrapper from '$lib/components/MaxWidthWrapper.svelte';
import { cn } from '$lib/utils';
import { faCircleArrowLeft } from '@fortawesome/free-solid-svg-icons';
import Fa from 'svelte-fa';
import { typography } from '../../../styles/tailwind/typography';
import dayjs from 'dayjs';
import buddhistEra from 'dayjs/plugin/buddhistEra';
import 'dayjs/locale/th';
import { formatDateTH } from '$lib/utils/date';
import Button from '$lib/components/Button.svelte';
import { modalShow } from '$lib/components/Modal/store';
import Modal from '$lib/components/Modal/Modal.svelte';
export let data;
const { document } = data;
modalShow.set(false);
dayjs.extend(buddhistEra);
</script>

<MaxWidthWrapper class="mt-10 space-y-6 lg:space-y-12 min-h-screen">
<div class="flex flex-col gap-3 items-start">
<button on:click={() => history.back()} class="lg:relative -left-14 top-12">
<Fa icon={faCircleArrowLeft} size="lg" />
</button>
<div class="flex items-center gap-4">
<h1 class={cn(typography({ variant: 'heading4' }), 'md:text-5xl lg:order-first')}>
{document?.title}
</h1>
</div>
<div>
<p>
โดย {document?.author.first_name}
</p>
<p>{formatDateTH(document?.updated_at || '')}</p>
</div>
</div>

<hr class="border-t border-gray-300 my-12" />

<div class="flex flex-col gap-6 lg:gap-12">
<p>{document?.content.repeat(8)}</p>
<div class="w-[342px] h-[220px] lg:w-[876px] lg:h-[500px] bg-sucu-gray-light" />
<Button class="w-fit mb-16" on:click={() => modalShow.set(true)}
>ดาวน์โหลดเอกสารที่เกี่ยวข้อง</Button
>
{#if modalShow}
<Modal />
{/if}
</div>
</MaxWidthWrapper>
8 changes: 8 additions & 0 deletions src/routes/stat/[id]/+page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { documents } from '$lib/mock/document';
import type { PageLoad } from './$types';
import 'dayjs/locale/th';

export const load: PageLoad = async ({ params }) => {
const document = documents.find((doc) => doc.id === params.id);
return { params, document };
};

0 comments on commit 35a17ba

Please sign in to comment.