added all logs page and presetalias added to mylogs

This commit is contained in:
suryacp23 2026-07-16 19:28:49 +05:30
parent 9ee67313f5
commit 9e423f0730
8 changed files with 117 additions and 10 deletions

View File

@ -6,6 +6,7 @@ import { OrdersPage } from './screens/OrdersPage'
import { CallsPage } from './screens/CallsPage'
import { StoresPage } from './screens/StoresPage'
import { DailyLogsPage } from './screens/DailyLogsPage'
import { AllDailyLogsPage } from './screens/AllDailyLogsPage'
import { AnalyticsPage } from './screens/AnalyticsPage'
function App() {
return (
@ -26,9 +27,13 @@ function App() {
<Route path="/daily" element={<DailyLogsPage />} />
<Route path="/daily/:instanceId" element={<DailyLogsPage />} />
<Route path="/all-daily" element={<AllDailyLogsPage />} />
<Route path="/all-daily/:instanceId" element={<AllDailyLogsPage />} />
<Route path="/analytics" element={<AnalyticsPage />} />
</Route>
<Route path="*" element={<Navigate to="/orders" replace />} />
<Route path="*" element={<Navigate to="/daily" replace />} />
</Routes>
</BrowserRouter>
</AuthProvider>

View File

@ -146,6 +146,7 @@ export class ZinoClient {
recordView(rvUid: string, params: RecordViewParams = {}): Promise<RecordViewResponse> {
return this.request<RecordViewResponse>('POST', `/app/${APP_ID}/view/recordview`, {
rv_template_uid: rvUid,
preset_alias: params.preset_alias,
search_query: {
page: params.page ?? 1,
limit: params.limit ?? 50,

View File

@ -53,6 +53,7 @@ export interface RecordViewParams {
sortDir?: 'asc' | 'desc';
search?: string;
filters?: Array<{ field_key: string; value: string; data_type?: string }>;
preset_alias?: string;
}
// --- Form schema (POST /app/{appId}/view/form-screens) ---

View File

@ -5,16 +5,17 @@ import type { WiredRecordViewProps } from './OrdersView';
import { DailyLogCard } from '../cards/DailyLogCard';
/** Daily Logs record view (Daily Reports workflow). */
export function DailyLogsView({ onRowClick, onPunchOutRow, pageSize, headerActions, refreshKey }: WiredRecordViewProps & { onPunchOutRow?: (row: any) => void }) {
export function DailyLogsView({ onRowClick, onPunchOutRow, pageSize, headerActions, refreshKey, preset_alias = "my_logs", title = "Daily Logs" }: WiredRecordViewProps & { onPunchOutRow?: (row: any) => void, preset_alias?: string, title?: string }) {
return (
<RecordView
client={dailyReportsClient}
rvUid={DAILY_REPORTS.recordViews.DAILY_LOGS}
title="Daily Logs"
title={title}
onRowClick={onRowClick}
pageSize={pageSize}
headerActions={headerActions}
refreshKey={refreshKey}
preset_alias={preset_alias}
sortBy="instance_id"
sortDir="desc"
hideChart

View File

@ -42,6 +42,8 @@ export interface RecordViewProps {
sortDir?: 'asc' | 'desc';
/** If true, the analytics chart will not be rendered even if data is returned */
hideChart?: boolean;
/** Pass a preset alias to apply server-side presets */
preset_alias?: string;
}
/**
@ -64,6 +66,7 @@ export function RecordView({
sortBy,
sortDir,
hideChart = false,
preset_alias,
}: RecordViewProps) {
const [page, setPage] = useState(1);
const [search, setSearch] = useState('');
@ -104,7 +107,7 @@ export function RecordView({
setLoading(true);
setError(null);
try {
const r = await client.recordView(rvUid, { page, limit: pageSize, search: debounced, filters: filtersParam, sortBy, sortDir });
const r = await client.recordView(rvUid, { preset_alias, page, limit: pageSize, search: debounced, filters: filtersParam, sortBy, sortDir });
if (live) setResp(r);
} catch (e) {
if (live) setError((e as { message?: string })?.message ?? 'Failed to load');
@ -116,7 +119,7 @@ export function RecordView({
return () => {
live = false;
};
}, [client, rvUid, page, pageSize, debounced, filtersParam, refreshKey, sortBy, sortDir]);
}, [client, rvUid, preset_alias, page, pageSize, debounced, filtersParam, refreshKey, sortBy, sortDir]);
const fields: RecordViewField[] = useMemo(() => {
const all = resp?.config.fields ?? [];

View File

@ -0,0 +1,95 @@
import { useNavigate, useParams } from 'react-router-dom';
import { Modal } from '../components/reusable';
import { DailyLogsView } from '../components/rv';
import { DailyLogDetail } from '../components/dv';
import { useState } from 'react';
import { ClipboardList } from 'lucide-react';
import { DynamicForm } from '../components/forms/DynamicForm';
import { DAILY_REPORTS } from '../api/config';
import { dailyReportsClient } from '../api/clients';
export function AllDailyLogsPage() {
const params = useParams();
const instanceId = params.instanceId ? Number(params.instanceId) : undefined;
const navigate = useNavigate();
const [isCreating, setIsCreating] = useState(false);
const [createTitle, setCreateTitle] = useState("Punch In");
const [punchOutInstanceId, setPunchOutInstanceId] = useState<number | string | null>(null);
const [punchOutTitle, setPunchOutTitle] = useState("Punch Out");
const [refreshKey, setRefreshKey] = useState(0);
return (
<>
<DailyLogsView
refreshKey={refreshKey}
preset_alias={undefined}
title="All Daily Logs"
onRowClick={(row) => {
const id = row.instance_id as number | string | undefined;
if (id != null) navigate(`/all-daily/${id}`);
}}
onPunchOutRow={(row) => {
setPunchOutInstanceId(row.instance_id as string | number);
setPunchOutTitle("Punch Out");
}}
/>
{/* Global Floating Action Button for Punch In */}
<button
onClick={() => { setIsCreating(true); setCreateTitle("Punch In"); }}
className="fixed bottom-24 right-6 w-[60px] h-[60px] bg-[var(--z-bg-primary-400)] rounded-3xl flex items-center justify-center shadow-[0_4px_12px_rgba(var(--z-bg-primary-400-rgb),0.4)] text-white z-40 hover:opacity-90 transition-transform hover:scale-105 active:scale-95 cursor-pointer"
>
<ClipboardList size={24} className="text-white" />
</button>
<Modal
open={isCreating}
onClose={() => setIsCreating(false)}
title={createTitle}
width="md"
>
<DynamicForm
client={dailyReportsClient}
activityId={DAILY_REPORTS.activities.INIT.uid}
onSuccess={() => {
setIsCreating(false);
setRefreshKey(k => k + 1);
}}
onCancel={() => setIsCreating(false)}
onActivityChange={(name) => setCreateTitle(name)}
/>
</Modal>
<Modal
open={punchOutInstanceId != null}
onClose={() => setPunchOutInstanceId(null)}
title={punchOutTitle}
width="md"
>
{punchOutInstanceId != null && (
<DynamicForm
client={dailyReportsClient}
activityId={DAILY_REPORTS.activities.PUNCH_OUT.uid}
instanceId={punchOutInstanceId}
onSuccess={() => {
setPunchOutInstanceId(null);
setRefreshKey(k => k + 1);
}}
onCancel={() => setPunchOutInstanceId(null)}
onActivityChange={(name) => setPunchOutTitle(name)}
/>
)}
</Modal>
<Modal
open={instanceId != null}
onClose={() => navigate(`/all-daily`)}
title={instanceId != null ? `Daily Log #${instanceId}` : undefined}
width="lg"
>
{instanceId != null && <DailyLogDetail instanceId={instanceId} />}
</Modal>
</>
);
}

View File

@ -52,9 +52,9 @@ export function ConsoleLayout() {
<nav
className="fixed bottom-0 inset-x-0 z-20 h-16 pb-[env(safe-area-inset-bottom)] bg-card border-t border-border-subtle grid shadow-[0_-2px_16px_rgba(11,27,59,0.06)]"
style={{ gridTemplateColumns: `repeat(${SCREENS.filter(t => t.key !== 'analytics').length}, minmax(0, 1fr))` }}
style={{ gridTemplateColumns: `repeat(${SCREENS.filter(t => t.key !== 'analytics' && t.key !== 'all-daily').length}, minmax(0, 1fr))` }}
>
{SCREENS.filter(t => t.key !== 'analytics').map((t) => {
{SCREENS.filter(t => t.key !== 'analytics' && t.key !== 'all-daily').map((t) => {
const Icon = t.icon;
return (
<NavLink

View File

@ -1,4 +1,4 @@
import { Store, Phone, ShoppingCart, ClipboardList, type LucideIcon } from 'lucide-react';
import { Store, Phone, ShoppingCart, ClipboardList, Home, type LucideIcon } from 'lucide-react';
import {
OrdersView,
CallsView,
@ -17,7 +17,7 @@ import {
import { AnalyticsPage } from './AnalyticsPage';
import { BarChart2 } from 'lucide-react';
export type ScreenKey = 'orders' | 'calls' | 'stores' | 'daily' | 'analytics';
export type ScreenKey = 'orders' | 'calls' | 'stores' | 'daily' | 'analytics' | 'all-daily';
export interface ScreenDef {
key: ScreenKey;
@ -31,10 +31,11 @@ export interface ScreenDef {
export const SCREENS: ScreenDef[] = [
{ key: 'analytics', label: 'Analytics', icon: BarChart2, View: AnalyticsPage as any },
{ key: 'daily', label: 'Home', icon: Home, View: DailyLogsView, Detail: DailyLogDetail, noun: 'Daily Log' },
{ key: 'orders', label: 'Orders', icon: ShoppingCart, View: OrdersView, Detail: OrderDetail, noun: 'Order' },
{ key: 'calls', label: 'Calls', icon: Phone, View: CallsView, Detail: CallDetail, noun: 'Call' },
{ key: 'stores', label: 'Stores', icon: Store, View: StoresView, Detail: StoreDetail, noun: 'Store' },
{ key: 'daily', label: 'Daily Logs', icon: ClipboardList, View: DailyLogsView, Detail: DailyLogDetail, noun: 'Daily Log' },
{ key: 'all-daily', label: 'All Logs', icon: ClipboardList, View: DailyLogsView, Detail: DailyLogDetail, noun: 'Daily Log' },
];
export function screenByKey(key: string | undefined): ScreenDef | undefined {