Skip to content

Commit

Permalink
FEAT: Add log prayer MVP (#288)
Browse files Browse the repository at this point in the history
* FEAT: Add log prayer MVP

* FEAT: Add active state in date selection
  • Loading branch information
mazipan authored Oct 31, 2024
1 parent 66b8d69 commit 1165620
Show file tree
Hide file tree
Showing 12 changed files with 253 additions and 27 deletions.
9 changes: 0 additions & 9 deletions .env.production

This file was deleted.

2 changes: 1 addition & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ jobs:
run: |
echo "> Start remove unused files..."
rm -rf .github/workflows .svelte-kit markdowns screenshoot scripts static src node_modules
rm -rf .all-contributorsrc .editorconfig .eslintignore .eslintrc.cjs .gitignore .kodiak.toml .npmrc .prettierignore .prettierrc package.json pnpm-lock.yaml postcss.config.js svelte.config.js tailwind.config.js tsconfig.json vite.config.ts .env.example .env.production .nvmrc
rm -rf .all-contributorsrc .editorconfig .eslintignore .eslintrc.cjs .gitignore .kodiak.toml .npmrc .prettierignore .prettierrc package.json pnpm-lock.yaml postcss.config.js svelte.config.js tailwind.config.js tsconfig.json vite.config.ts .env.example .nvmrc
echo "> Copy build directory..."
cp -r build/. ./
Expand Down
3 changes: 2 additions & 1 deletion scripts/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ export const staticUrls = [
'/sync/',
'/tahlil/',
'/tasbih/',
'/wirid/'
'/wirid/',
'/pencatat-ibadah/'
];
15 changes: 5 additions & 10 deletions src/lib/PrayerTimeCard.svelte
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
<script lang="ts">
import CardShadow from './CardShadow.svelte';
import type { PrayerKey, PrayerTimings } from './types';
import dayjs from 'dayjs';
import relativeTime from "dayjs/plugin/relativeTime";
import duration from "dayjs/plugin/duration";
import 'dayjs/locale/id'
import { onMount } from 'svelte';
import { getDayjs, getDayjsFormatted, getMinuteDuration } from '$lib/utils/date';
import { activeTheme } from '../store';
dayjs.locale('id')
dayjs.extend(relativeTime);
dayjs.extend(duration);
interface Props {
timings?: PrayerTimings | null;
prayerKey: PrayerKey;
Expand All @@ -23,14 +18,14 @@
let durationText: string = $state('');
onMount(async () => {
const now = dayjs();
const now = getDayjs();
const timeStr = `${timings?.[prayerKey] || ''}`.substring(0, 5);
const prayerTime = dayjs(`${now.format('YYYY-MM-DD')} ${timeStr}`, 'YYYY-MM-DD HH:mm');
const prayerTime = getDayjsFormatted(`${now.format('YYYY-MM-DD')} ${timeStr}`, 'YYYY-MM-DD HH:mm');
const diffTime = prayerTime.diff(now, 'minute');
isPast = diffTime < 0;
durationText = dayjs.duration(diffTime, "minutes").humanize(true);
durationText = getMinuteDuration(diffTime);
});
</script>
Expand Down
12 changes: 10 additions & 2 deletions src/lib/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ export const CONSTANTS = {
LAST_VERSES: 'vres',
LOCATION: 'loc',
PRAYER: 'pryr',
THEME: 'theme'
THEME: 'theme',
LOG_PRAYER: 'log'
},
BISMILLAH: '﷽'
};
Expand Down Expand Up @@ -80,6 +81,9 @@ export const META_DESC_TASBIH = `Tasbih online, mempermudah menghitung Dzikirmu
export const META_TITLE_JADWAL_SHOLAT = `Jadwal sholat | ${TITLE_CONSTANTS.TITLE_META}`;
export const META_DESC_JADWAL_SHOLAT = `Jadwal sholat sesuai lokasi 💯 gratis, ❌ tanpa iklan, ❌ tanpa analitik`;

export const META_TITLE_PENCATAT_IBADAH = `Pencatat Ibadah | ${TITLE_CONSTANTS.TITLE_META}`;
export const META_DESC_PENCATAT_IBADAH = `Pencatat Ibadah ${postfix(false)}`;

export const META_TITLE_SURAH = (name: string) =>
`Qur'an Surat ${name} | ${TITLE_CONSTANTS.TITLE_META}`;
export const META_DESC_SURAH = (name: string) => `Qur'an Surat ${name} ${postfix(true)}`;
Expand All @@ -91,6 +95,7 @@ export const META_TITLE_AYAH = (
translation?: string
) =>
`QS ${surahid}:${verseid}, Surat ${name} - ${translation}, Ayat ${verseid || 1} | ${TITLE_CONSTANTS.TITLE_META}`;

export const META_DESC_AYAH = (
verseid: string,
surahid?: string,
Expand All @@ -117,7 +122,8 @@ export type PageVariant =
| 'TASBIH'
| 'MAKKIYAH'
| 'MADANIYAH'
| 'JADWAL_SHOLAT';
| 'JADWAL_SHOLAT'
| 'CATAT_IBADAH';

export const SEO_TEXT = {
ALL_SURAH:
Expand All @@ -142,6 +148,8 @@ export const SEO_TEXT = {
'Tasbih online, mempermudah menghitung Dzikirmu. Langsung dari peramban, tanpa iklan, tanpa analitik, privasi aman dan gratis sepenuhnya.',
JADWAL_SHOLAT:
'Jadwal sholat terlengkap. Langsung dari peramban, tanpa iklan, tanpa analitik, privasi aman dan gratis sepenuhnya.',
CATAT_SHOLAT:
'Jadwal sholat terlengkap. Langsung dari peramban, tanpa iklan, tanpa analitik, privasi aman dan gratis sepenuhnya.',
SURAH_DETAIL: '',
AYAT_DETAIL: ''
};
Expand Down
2 changes: 2 additions & 0 deletions src/lib/utils/array.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const range = (start: number, stop: number, step = 1) =>
Array.from({ length: (stop - start) / step + 1 }, (_, i) => start + i * step)
40 changes: 40 additions & 0 deletions src/lib/utils/date.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import dayjs from 'dayjs';
import relativeTime from "dayjs/plugin/relativeTime";
import duration from "dayjs/plugin/duration";
import 'dayjs/locale/id'

dayjs.locale('id')
dayjs.extend(relativeTime);
dayjs.extend(duration);

export const getDayjs = () => {
return dayjs();
};

export const getDayjsFormatted = (dateString: string, format: string) => {
return dayjs(dateString, format)
};

export const getDayInMonth = (dateString: string) => {
return dayjs(dateString).daysInMonth()
};

export const getMonthName = () => {
return dayjs().format('MMMM')
};

export const getCurrentDate = () => {
return dayjs().toDate().getDate();
};

export const formatDate = (date: string, format: string) => {
return dayjs(date).format(format);
};

export const formatYYYYMMDD = (date: string) => {
return dayjs(date).format('YYYY-MM-DD');
};

export const getMinuteDuration = (diffTime: number) => {
return dayjs.duration(diffTime, "minutes").humanize(true);
};
11 changes: 10 additions & 1 deletion src/routes/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
settingAutoNext,
pinnedSurah,
lastReadVerses,
settingLocation
settingLocation,
logPrayer,
} from '../store';
import '../app.css';
Expand Down Expand Up @@ -85,6 +86,14 @@
} else {
settingLocation.set(null);
}
const storageLogPrayer = localStorage.getItem(CONSTANTS.STORAGE_KEY.LOG_PRAYER);
if (storageLogPrayer) {
const parsedValue = JSON.parse(storageLogPrayer);
logPrayer.set(parsedValue);
} else {
settingLocation.set(null);
}
}
}
});
Expand Down
4 changes: 4 additions & 0 deletions src/routes/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@
{
href: '/jadwal-sholat/',
title: '⏰ Jadwal Sholat'
},
{
href: '/pencatat-ibadah/',
title: '⏺️ Pencatat Ibadah'
}
];
</script>
Expand Down
149 changes: 149 additions & 0 deletions src/routes/pencatat-ibadah/+page.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
<script lang="ts">
import Breadcrumb from '$lib/Breadcrumb.svelte';
import MetaTag from '$lib/MetaTag.svelte';
import SeoText from '$lib/SeoText.svelte';
import {
CONSTANTS,
META_DESC_PENCATAT_IBADAH,
META_TITLE_PENCATAT_IBADAH,
TITLE_CONSTANTS
} from '$lib/constants';
import { formatDate, getCurrentDate, getDayInMonth } from '$lib/utils/date';
import { range } from '$lib/utils/array';
import type { PrayerKey } from '$lib/types';
import CardShadow from '$lib/CardShadow.svelte';
import { logPrayer, type LogPrayerItemKey, type LogPrayerItemValue, type LogPrayerValue } from '$store';
let dayInMonth = getDayInMonth(new Date().toISOString());
let dayRanges = range(1, dayInMonth);
let selectedDate = $state(getCurrentDate());
let selectedDateFormatted = $derived.by(() => {
const nDate = new Date();
nDate.setDate(selectedDate);
const res = formatDate(nDate.toISOString(), 'DD MMMM YYYY');
return res;
});
let selectedYYYYMMDD = $derived.by(() => {
const nDate = new Date();
nDate.setDate(selectedDate);
const res = formatDate(nDate.toISOString(), 'YYYYMMDD');
return res;
});
const PRAYER_LIST: Array<{
key: PrayerKey;
title: string;
id: LogPrayerItemKey;
}> = [
{
key: 'Fajr',
title: 'Subuh',
id: '1'
},
{
key: 'Dhuhr',
title: 'Dzuhur',
id: '2'
},
{
key: 'Asr',
title: 'Ashar',
id: '3'
},
{
key: 'Maghrib',
title: 'Maghrib',
id: '4'
},
{
key: 'Isha',
title: 'Isya',
id: '5'
}
];
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
let handleCheckUncheck = (e) => {
const id = e.target.value.toString() as LogPrayerItemKey;
const isChecked = e.target.checked as boolean;
logPrayer.update((val) => {
const newItem = {
[id]: isChecked ? 1 : 0 as LogPrayerItemValue
} as LogPrayerValue;
if (val) {
if (val[selectedYYYYMMDD]) {
val[selectedYYYYMMDD] = {
...val[selectedYYYYMMDD],
...newItem,
}
} else {
val[selectedYYYYMMDD] = newItem;
}
} else {
val = {
[selectedYYYYMMDD]: newItem
};
}
localStorage.setItem(CONSTANTS.STORAGE_KEY.LOG_PRAYER, JSON.stringify(val));
return val
});
}
</script>

<svelte:head>
<MetaTag
title={META_TITLE_PENCATAT_IBADAH}
desc={META_DESC_PENCATAT_IBADAH}
url={`${TITLE_CONSTANTS.PATH}pencatat-ibadah/`}
/>
</svelte:head>

<div class="flex gap-2 px-4 mb-4">
<h1 class="text-3xl font-bold">⏺️ Pencatat Ibadah</h1>
</div>

<div class="px-4 mb-4">
<Breadcrumb items={[{ text: '🏠 Beranda', href: '/' }]} />
</div>

<div class="px-4 flex flex-col gap-2">
<p class="text-lg">Catatan ibadah pada {selectedDateFormatted}</p>
<div class="flex gap-2 w-full overflow-x-auto pb-4 pt-2 px-4 mt-2">
{#each dayRanges as day (day)}
<button
class={`h-12 w-12 rounded flex items-center justify-center p-4 border focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 ${day === selectedDate ? 'bg-primary font-bold border-blue-500' : 'bg-secondary'}`}
onclick={() => {
selectedDate = day;
}}
>
{day}
</button>
{/each}
</div>
<div class="grid gap-2">
{#each PRAYER_LIST as prayer (prayer.key)}
<CardShadow class="flex items-center">
<input
id={`chk-${prayer.id}`}
type="checkbox"
value={prayer.id}
name={prayer.title}
onchange={handleCheckUncheck}
checked={$logPrayer && $logPrayer?.[selectedYYYYMMDD] ? $logPrayer[selectedYYYYMMDD]?.[`${prayer.id}` as LogPrayerItemKey] === 1 : false}
class="peer w-6 h-6 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600"
/>
<label for={`chk-${prayer.id}`} class="w-full ms-2 text-sm font-medium text-foreground peer-checked:line-through">
{prayer.title}
</label>
</CardShadow>
{/each}
</div>
</div>

<SeoText variant="CATAT_IBADAH" />
18 changes: 15 additions & 3 deletions src/routes/sync/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@
activeTheme,
settingLocation,
lastReadVerses,
pinnedSurah
pinnedSurah,
logPrayer,
} from '../../store';
import { toast } from '../../store/toast';
import { CONSTANTS, TITLE_CONSTANTS } from '$lib/constants';
Expand Down Expand Up @@ -140,7 +141,8 @@
district: 'N/A'
},
[CONSTANTS.STORAGE_KEY.LAST_VERSES]: [],
[CONSTANTS.STORAGE_KEY.PINNED_SURAH]: []
[CONSTANTS.STORAGE_KEY.PINNED_SURAH]: [],
[CONSTANTS.STORAGE_KEY.LOG_PRAYER]: {}
};
}
};
Expand All @@ -155,7 +157,8 @@
[CONSTANTS.STORAGE_KEY.THEME]: $activeTheme || '',
[CONSTANTS.STORAGE_KEY.LOCATION]: $settingLocation || null,
[CONSTANTS.STORAGE_KEY.LAST_VERSES]: $lastReadVerses || null,
[CONSTANTS.STORAGE_KEY.PINNED_SURAH]: $pinnedSurah || null
[CONSTANTS.STORAGE_KEY.PINNED_SURAH]: $pinnedSurah || null,
[CONSTANTS.STORAGE_KEY.LOG_PRAYER]: $logPrayer || null
};
const dbRef = collection(db, 'progress');
const q = query(dbRef, where('uid', '==', currentUser?.uid));
Expand Down Expand Up @@ -273,6 +276,15 @@
);
}
// log prayer
if (data?.[CONSTANTS.STORAGE_KEY.LOG_PRAYER]) {
logPrayer.set(data?.[CONSTANTS.STORAGE_KEY.LOG_PRAYER]);
localStorage.setItem(
CONSTANTS.STORAGE_KEY.LOG_PRAYER,
JSON.stringify(data?.[CONSTANTS.STORAGE_KEY.LOG_PRAYER] || [])
);
}
currentRemoteProgress = doc.data();
}
});
Expand Down
Loading

0 comments on commit 1165620

Please sign in to comment.