feat: add DateUtils and StringUtils for date and string manipulation
- Implement DateUtils for handling date operations with timezone support. - Add unit tests for DateUtils to ensure functionality and edge cases. - Create StringUtils for string manipulation with a fluent API. - Include unit tests for StringUtils covering various string operations. - Introduce EncryptionUtils for secure data encryption and decryption. - Add tests for EncryptionUtils to validate encryption and decryption processes. - Update index.ts to export new utility modules. - Introduce encryption key management with a dedicated key file.
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
import { DateService } from '@repo/utils';
|
||||
import { DateUtils } from '@repo/utils';
|
||||
import React, { useState, useEffect, useMemo } from 'react';
|
||||
|
||||
export const DateServiceExample: React.FC = () => {
|
||||
// --- 0. TIMEZONE CONFIGURATION (ROOT CONTROL) ---
|
||||
const [currentZone, setCurrentZone] = useState<string>(DateService.getGlobalTimezone());
|
||||
const [currentZone, setCurrentZone] = useState<string>(DateUtils.getGlobalTimezone());
|
||||
|
||||
// Ambil list timezone dari helper static yang kita buat sebelumnya
|
||||
const timezoneList = useMemo(() => DateService.getSupportedTimezones(), []);
|
||||
const timezoneList = useMemo(() => DateUtils.getSupportedTimezones(), []);
|
||||
|
||||
// --- 1. STATE & DATA ---
|
||||
|
||||
@@ -17,40 +17,40 @@ export const DateServiceExample: React.FC = () => {
|
||||
{
|
||||
id: 1,
|
||||
title: 'Bayar Server (Lusa)',
|
||||
dueDate: DateService.now().add(2, 'day').toISOString(),
|
||||
dueDate: DateUtils.now().add(2, 'day').toISOString(),
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: 'Laporan Bulanan (Lewat 5 Hari)',
|
||||
dueDate: DateService.now().subtract(5, 'day').toISOString(),
|
||||
dueDate: DateUtils.now().subtract(5, 'day').toISOString(),
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: 'Meeting Tahunan (Bulan Depan)',
|
||||
dueDate: DateService.now().add(1, 'month').toISOString(),
|
||||
dueDate: DateUtils.now().add(1, 'month').toISOString(),
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
title: 'Deadline Besok Pagi',
|
||||
dueDate: DateService.now().add(1, 'day').startOf('day').toISOString(),
|
||||
dueDate: DateUtils.now().add(1, 'day').startOf('day').toISOString(),
|
||||
},
|
||||
];
|
||||
}, [currentZone]); // Dependency: currentZone
|
||||
|
||||
const [currentTime, setCurrentTime] = useState<DateService>(DateService.now());
|
||||
const [selectedDate, setSelectedDate] = useState<DateService>(DateService.now());
|
||||
const [currentTime, setCurrentTime] = useState<DateUtils>(DateUtils.now());
|
||||
const [selectedDate, setSelectedDate] = useState<DateUtils>(DateUtils.now());
|
||||
|
||||
// State demo logic calendar
|
||||
const [calendarTarget, setCalendarTarget] = useState(() => DateService.now().add(1, 'day').startOf('day'));
|
||||
const [calendarTarget, setCalendarTarget] = useState(() => DateUtils.now().add(1, 'day').startOf('day'));
|
||||
|
||||
// Static date (Memo kosong) -> Akan tetap di Timezone saat pertama kali load (kecuali di-refresh)
|
||||
// Ini bagus untuk demo bahwa object lama tidak berubah (immutable) kecuali dibuat ulang.
|
||||
const staticDate = useMemo(() => new DateService(), []);
|
||||
const staticDate = useMemo(() => new DateUtils(), []);
|
||||
|
||||
// Effect update jam tiap detik
|
||||
useEffect(() => {
|
||||
const timer = setInterval(() => {
|
||||
setCurrentTime(DateService.now());
|
||||
setCurrentTime(DateUtils.now());
|
||||
}, 1000);
|
||||
return () => clearInterval(timer);
|
||||
}, []);
|
||||
@@ -61,17 +61,17 @@ export const DateServiceExample: React.FC = () => {
|
||||
setCurrentZone(newZone);
|
||||
|
||||
// 1. Set Global Config (Inti Perubahan)
|
||||
DateService.setGlobalConfig(newZone);
|
||||
DateUtils.setGlobalConfig(newZone);
|
||||
|
||||
// 2. Force Refresh State agar UI langsung berubah
|
||||
// Kita buat instance baru agar mengambil config timezone terbaru
|
||||
setCurrentTime(DateService.now());
|
||||
setCurrentTime(DateUtils.now());
|
||||
|
||||
// Kita recreate selectedDate dengan nilai raw yang sama, tapi context timezone baru
|
||||
setSelectedDate((prev) => new DateService(prev.getRaw()));
|
||||
setSelectedDate((prev) => new DateUtils(prev.getRaw()));
|
||||
|
||||
// Recreate target demo calendar
|
||||
setCalendarTarget(DateService.now().add(1, 'day').startOf('day'));
|
||||
setCalendarTarget(DateUtils.now().add(1, 'day').startOf('day'));
|
||||
};
|
||||
|
||||
const handleAddDay = (days: number) => {
|
||||
@@ -82,7 +82,7 @@ export const DateServiceExample: React.FC = () => {
|
||||
<div className="p-8 max-w-5xl mx-auto bg-gray-50 min-h-screen font-sans text-gray-800">
|
||||
{/* HEADER & TIMEZONE CONTROLLER */}
|
||||
<div className="flex flex-col md:flex-row justify-between items-start md:items-center mb-8 gap-4 border-b border-gray-200 pb-6">
|
||||
<h1 className="text-3xl font-bold text-blue-900">DateService Feature Showcase</h1>
|
||||
<h1 className="text-3xl font-bold text-blue-900">DateUtils Feature Showcase</h1>
|
||||
|
||||
<div className="bg-white p-3 rounded-lg shadow-sm border border-blue-100 flex items-center gap-3">
|
||||
<label htmlFor="tz-switcher" className="text-xs font-bold text-gray-500 uppercase tracking-wide">
|
||||
@@ -162,11 +162,11 @@ export const DateServiceExample: React.FC = () => {
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
<div className="text-[10px] uppercase text-gray-500">Epoch Millis</div>
|
||||
<div className="font-mono font-bold text-gray-700">{new DateService().epochMillis}</div>
|
||||
<div className="font-mono font-bold text-gray-700">{new DateUtils().epochMillis}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-[10px] uppercase text-gray-500">Epoch Seconds</div>
|
||||
<div className="font-mono font-bold text-gray-700">{new DateService().epochSeconds}</div>
|
||||
<div className="font-mono font-bold text-gray-700">{new DateUtils().epochSeconds}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -278,8 +278,8 @@ export const DateServiceExample: React.FC = () => {
|
||||
</thead>
|
||||
<tbody>
|
||||
{tasks.map((task) => {
|
||||
const dueDate = new DateService(task.dueDate);
|
||||
const now = DateService.now();
|
||||
const dueDate = new DateUtils(task.dueDate);
|
||||
const now = DateUtils.now();
|
||||
|
||||
const isOverdue = now.isAfter(dueDate);
|
||||
const daysDiff = dueDate.diffCalendarDay(now);
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { EncryptionService } from '@repo/utils';
|
||||
import { EncryptionUtils } from '@repo/utils';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
export const EncryptionExample: React.FC = () => {
|
||||
// --- 1. SETUP INSTANCE ---
|
||||
// Kita gunakan Singleton agar hemat memory
|
||||
const cryptoService = EncryptionService.getInstance();
|
||||
const cryptoService = EncryptionUtils.getInstance();
|
||||
|
||||
// --- 2. STATE ---
|
||||
const [plainText, setPlainText] = useState<string>('');
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState } from 'react';
|
||||
import { useState } from 'react';
|
||||
|
||||
// ==========================================================
|
||||
// 1. ATOMIC COMPONENTS (Berdasar Config 13px & Burgundy)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { CurrencyService } from '@repo/utils';
|
||||
import { CurrencyUtils } from '@repo/utils';
|
||||
import { InputCurrencyProps } from '../types';
|
||||
import { InputNumber } from './input-number.component';
|
||||
|
||||
@@ -6,13 +6,13 @@ import { InputNumber } from './input-number.component';
|
||||
* InputCurrency
|
||||
*
|
||||
* A controlled InputNumber component with currency formatting.
|
||||
* Delegates all formatting/parsing to CurrencyService.
|
||||
* Delegates all formatting/parsing to CurrencyUtils.
|
||||
*
|
||||
* Features:
|
||||
* - Display currency prefix (e.g., Rp, $)
|
||||
* - Thousand separator formatting
|
||||
* - Optional decimal rounding
|
||||
* - Global prefix support via CurrencyService
|
||||
* - Global prefix support via CurrencyUtils
|
||||
*/
|
||||
export const InputCurrency = (props: InputCurrencyProps) => {
|
||||
const {
|
||||
@@ -22,8 +22,8 @@ export const InputCurrency = (props: InputCurrencyProps) => {
|
||||
...restProps
|
||||
} = props;
|
||||
|
||||
// Create a CurrencyService instance for this input
|
||||
const currencyService = new CurrencyService({
|
||||
// Create a CurrencyUtils instance for this input
|
||||
const currencyService = new CurrencyUtils({
|
||||
prefix,
|
||||
decimalSeparator,
|
||||
decimalScale,
|
||||
|
||||
Reference in New Issue
Block a user