Dashboard Feature: A Deep Dive

by RICHARD 31 views
Iklan Headers

Streamlining Your Workflow: A Deep Dive into the Dashboard Feature

Hey there, let's dive into the fascinating world of the dashboard feature! This is the central hub you'll land on after logging in, and it's designed to give you a quick overview of everything you need to know about your users' plans. We're talking about a user-friendly interface that puts all the critical information right at your fingertips. It's like having a command center for your daily tasks, ensuring you stay on top of your game. We're going to go through every part to learn how it all works, so buckle up!

Dashboard Overview: Your Daily Command Center

Understanding the Dashboard

Dashboard serves as your primary interface upon login. It's all about providing a comprehensive view of each user's plan status. The aim is to simplify your work, make sure you know what's happening with everyone you're helping, and make things easier for you. The main purpose of the dashboard is to get you quick updates on everyone's plans. This lets you see what you need to do right away, without having to dig around.

Essential Display Elements

The dashboard is split into sections, each of which tells you something different. Let's break down these items.

  • Staff Information: You'll see your name, role, and the permissions you have. This section makes sure you know who you are and what you can do.

  • User List Table: This table is the star of the show, and it's where you'll find all the important info about your users. Let's go through each part:

    • Full Name: Click on the user's name, and you'll be taken to their individual support plan page. This makes it easy to access detailed info.
    • Plan Progress: See which stage of their plan each user is in, such as assessment or draft. This helps you know what to focus on.
    • Next Update: See when each plan is due for renewal, and how many days are left. This helps you schedule your work.
    • Monitoring Deadline: If monitoring is required, you'll see the deadline and how many days are left. This makes sure you don't miss any important checks.
    • Details: This lets you access more data like individual support plans, assessments, and PDF lists. Plus, you can update or delete user info.

    If there are no users registered, a message will display: "No users registered". This makes sure the page stays clean and easy to use.

Key Functionality

The dashboard is more than just a place to view information; it also allows you to act. Here's what you can do:

  • New User Registration: Start the process of registering new users. This will include a review process.
  • User Information Changes: Modify user information. This function will also follow a review process.
  • User Removal: Delete users, if needed. As with the other actions, this involves a review process.

This setup makes sure you can see the details you need, manage the important stuff, and get things done fast. With these elements, the dashboard is meant to make things easy.

In-Depth Design: Dashboard and Billing Features

Alright, guys, let's get down to the nitty-gritty of the dashboard and billing functions. We'll check out the backend and frontend designs, so you understand how the data moves and how it all comes together.

1. Backend Design: The Data Source

The backend is the engine that provides all the data the frontend needs. We design the APIs to retrieve information efficiently in a single API call.

1.1. API Endpoints

Here's a simple table showing the API endpoint that you'll be working with:

HTTP Method Endpoint URL Function Summary
GET /api/v1/dashboard Get dashboard info for the logged-in staff.

1.2. Response Data Schema (schemas/dashboard.py)

We're super strict when it comes to how data is structured. The frontend uses this contract to display the UI. Here's the basic format:

# app/schemas/dashboard.py
from pydantic import BaseModel
from datetime import date
from typing import List, Optional
from app.models.enums import SupportPlanStep, BillingStatus

class DashboardRecipient(BaseModel):
    """ใƒ€ใƒƒใ‚ทใƒฅใƒœใƒผใƒ‰ใซ่กจ็คบใ™ใ‚‹ๅˆฉ็”จ่€…ไธ€ไบบใฎใ‚ตใƒžใƒชใƒผ"""
    id: uuid.UUID
    full_name: str
    furigana: str
    current_cycle_number: int
    latest_step: Optional[SupportPlanStep] # ๆœ€ๆ–ฐใฎๆœชๅฎŒไบ†ใ‚นใƒ†ใƒƒใƒ—
    next_renewal_deadline: Optional[date]
    monitoring_due_date: Optional[date]

class DashboardData(BaseModel):
    """ใƒ€ใƒƒใ‚ทใƒฅใƒœใƒผใƒ‰ๅ…จไฝ“ใฎใƒ‡ใƒผใ‚ฟ"""
    office_name: str
    current_user_count: int
    max_user_count: int
    billing_status: BillingStatus
    recipients: List[DashboardRecipient]

1.3. Service Layer Logic (services/dashboard_service.py)

When GET /api/v1/dashboard is called, this service builds the DashboardData. This is what happens behind the scenes:

  1. The service finds the office the logged-in staff belongs to based on staff information.
  2. Gets the office name and billing status (billing_status).
  3. Counts the number of users (WelfareRecipient) linked to the office as current_user_count.
  4. For each user, it does the following (using selectinload to avoid the N+1 problem): a. Gets the SupportPlanCycle record where is_latest_cycle=True. b. From the SupportPlanStatus associated with that cycle, it finds the first record where completed=False as latest_step. c. Retrieves the cycle's next_renewal_deadline and the related status's monitoring_due_date.
  5. Finally, it packages the data into the DashboardData schema and sends it back.

2. Frontend Design: The Data Display & Processor

The frontend takes the data from the backend and formats it for the UI. It handles both displaying and transforming the data.

2.1. Data Retrieval

The frontend uses @tanstack/react-query's useQuery hook (or SWR) to fetch data from the /api/v1/dashboard endpoint.

const { data, isLoading, error } = useQuery({
  queryKey: ['dashboard'],
  queryFn: () => api.get('/dashboard')
});
  • While isLoading is true, a spinner will be shown.
  • If an error occurs, an error message will be shown.
  • If data.recipients is empty, a message saying "No users registered" will be displayed.

2.2. Data Processing and Display Logic

The frontend transforms the raw data into something easy to read and display in the UI.

  • Plan Progress: We use an object to map the latest_step enum values (like 'staff_meeting') to text and colors.
const stepDisplayMap = {
  assessment: { text: "ใ‚ขใ‚ปใ‚นใƒกใƒณใƒˆ", color: "bg-blue-100 text-blue-800" },
  draft_plan: { text: "ๅ€‹ๅˆฅๅŽŸๆกˆ", color: "bg-purple-100 text-purple-800" },
  staff_meeting: { text: "ๆ‹…ๅฝ“่€…ไผš่ญฐ", color: "bg-pink-100 text-pink-800" },
  monitoring: { text: "ใƒขใƒ‹ใ‚ฟใƒชใƒณใ‚ฐ", color: "bg-orange-100 text-orange-800" }
};
  • Next Renewal Date & Monitoring Deadline: We use the date-fns library to calculate the days remaining dynamically. This calculation happens within the UI component.
import { differenceInDays, format } from 'date-fns';

const renderDeadline = (deadline) => {
  if (!deadline) return '---';
  const daysLeft = differenceInDays(new Date(deadline), new Date());

  if (daysLeft < 0) return <span className="text-red-500">ๆœŸ้™ๅˆ‡ใ‚Œ</span>;
  if (daysLeft <= 30) return <span className="text-yellow-500">ๆฎ‹ใ‚Š{daysLeft}ๆ—ฅ</span>;
  return `ๆฎ‹ใ‚Š{daysLeft}ๆ—ฅ`;
};

2.3. User Information (Buttons)

  • The "Individual Support Plan", "PDF Viewing", "Assessment Sheet", and "Edit" buttons use Next.js's <Link> component to take users to the appropriate pages.
  • The "Delete" button shows a confirmation modal when clicked. If confirmed, it calls DELETE /api/v1/recipients/{recipient_id}.

keikakun_back (Backend Structure)

Here's the structure of the backend:

keikakun_back/
โ””โ”€โ”€ app/
    โ”œโ”€โ”€ api/
    โ”‚   โ””โ”€โ”€ v1/
    โ”‚       โ””โ”€โ”€ endpoints/
    โ”‚           โ”œโ”€โ”€ dashboard.py         # ใ€ๆ–ฐ่ฆใ€‘GET /api/v1/dashboard ใ‚จใƒณใƒ‰ใƒใ‚คใƒณใƒˆใ‚’ๅฎš็พฉใ™ใ‚‹ใƒ•ใ‚กใ‚คใƒซ
    โ”‚           โ”œโ”€โ”€ recipients.py        # ้–ข้€ฃ: POST /recipients (่ชฒ้‡‘ใƒใ‚งใƒƒใ‚ฏ), DELETE /recipients/{id}
    โ”‚           โ””โ”€โ”€ stripe.py            # ใ€ๆ–ฐ่ฆใ€‘POST /stripe/create-checkout-session ใชใฉๆฑบๆธˆ้–ข้€ฃใ‚จใƒณใƒ‰ใƒใ‚คใƒณใƒˆ
    โ”œโ”€โ”€ crud/
    โ”‚   โ”œโ”€โ”€ crud_office.py             # ้–ข้€ฃ: ไบ‹ๆฅญๆ‰€ใฎๅˆฉ็”จ่€…ๆ•ฐใ‚’ใ‚ซใ‚ฆใƒณใƒˆใ™ใ‚‹ใŸใ‚ใซๅˆฉ็”จ
    โ”‚   โ”œโ”€โ”€ crud_welfare_recipient.py  # ้–ข้€ฃ: ๅˆฉ็”จ่€…ใจ้–ข้€ฃๆƒ…ๅ ฑใ‚’ๅ–ๅพ—
    โ”‚   โ””โ”€โ”€ crud_support_plan_cycle.py # ้–ข้€ฃ: ๅˆฉ็”จ่€…ใฎๆœ€ๆ–ฐใ‚ตใ‚คใ‚ฏใƒซๆƒ…ๅ ฑใ‚’ๅ–ๅพ—
    โ”œโ”€โ”€ models/
    โ”‚   โ””โ”€โ”€ office.py                  # ้–ข้€ฃ: billing_status, stripe_customer_id ใ‚ซใƒฉใƒ ใ‚’ๆŒใค
    โ”œโ”€โ”€ schemas/
    โ”‚   โ””โ”€โ”€ dashboard.py               # ใ€ๆ–ฐ่ฆใ€‘DashboardData, DashboardRecipient ใฎPydanticใ‚นใ‚ญใƒผใƒžใ‚’ๅฎš็พฉ
    โ””โ”€โ”€ services/
        โ”œโ”€โ”€ dashboard_service.py       # ใ€ๆ–ฐ่ฆใ€‘ใƒ€ใƒƒใ‚ทใƒฅใƒœใƒผใƒ‰ๆƒ…ๅ ฑ๏ผˆๅˆฉ็”จ่€…ใ‚ตใƒžใƒชใƒผ๏ผ‰ใ‚’ๆง‹็ฏ‰ใ™ใ‚‹ใƒ“ใ‚ธใƒใ‚นใƒญใ‚ธใƒƒใ‚ฏ
        โ””โ”€โ”€ stripe_service.py          # ใ€ๆ–ฐ่ฆใ€‘Stripe APIใจใฎ้€ฃๆบใ€Webhookๅ‡ฆ็†ใชใฉใฎใƒ“ใ‚ธใƒใ‚นใƒญใ‚ธใƒƒใ‚ฏ

keikakun_front (Frontend Structure)

Hereโ€™s the structure of the frontend:

keikakun_front/
โ””โ”€โ”€ app/
    โ”œโ”€โ”€ dashboard/
    โ”‚   โ”œโ”€โ”€ components/
    โ”‚   โ”‚   โ”œโ”€โ”€ DashboardHeader.tsx    # ใ€ๆ–ฐ่ฆใ€‘ใƒ˜ใƒƒใƒ€ใƒผ้ƒจๅˆ†๏ผˆไบ‹ๆฅญๆ‰€ๅใ€ๅˆฉ็”จ่€…ๆ•ฐ/ไธŠ้™ใชใฉ๏ผ‰
    โ”‚   โ”‚   โ”œโ”€โ”€ DashboardTable.tsx     # ใ€ๆ–ฐ่ฆใ€‘ๅˆฉ็”จ่€…ไธ€่ฆงใƒ†ใƒผใƒ–ใƒซใฎ้ชจๆ ผ
    โ”‚   โ”‚   โ”œโ”€โ”€ DashboardTableRow.tsx  # ใ€ๆ–ฐ่ฆใ€‘ใƒ†ใƒผใƒ–ใƒซใฎๅ„่กŒใ€‚ใƒ‡ใƒผใ‚ฟๅŠ ๅทฅใƒญใ‚ธใƒƒใ‚ฏใ‚’ๅซใ‚€
    โ”‚   โ”‚   โ””โ”€โ”€ CreateRecipientButton.tsx # ใ€ๆ–ฐ่ฆใ€‘่ชฒ้‡‘ใƒญใ‚ธใƒƒใ‚ฏใ‚’ๅซใ‚€ใ€Œ+ใ€ใƒœใ‚ฟใƒณ
    โ”‚   โ”œโ”€โ”€ hooks/
    โ”‚   โ”‚   โ””โ”€โ”€ useDashboard.ts        # ใ€ๆ–ฐ่ฆใ€‘useQueryใ‚’ไฝฟใฃใฆ /api/v1/dashboard ใ‹ใ‚‰ใƒ‡ใƒผใ‚ฟใ‚’ๅ–ๅพ—ใ™ใ‚‹ใ‚ซใ‚นใ‚ฟใƒ ใƒ•ใƒƒใ‚ฏ
    โ”‚   โ””โ”€โ”€ page.tsx                   # ใƒ€ใƒƒใ‚ทใƒฅใƒœใƒผใƒ‰ใƒšใƒผใ‚ธใฎใƒกใ‚คใƒณใ‚ณใƒณใƒใƒผใƒใƒณใƒˆ(ใ‚ตใƒผใƒใƒผใ‚ณใƒณใƒใƒผใƒใƒณใƒˆ)
    โ”œโ”€โ”€ office/
    โ”‚   โ””โ”€โ”€ billing/
    โ”‚       โ”œโ”€โ”€ components/
    โ”‚       โ”‚   โ””โ”€โ”€ BillingModal.tsx   # ใ€ๆ–ฐ่ฆใ€‘่ชฒ้‡‘ใƒ—ใƒฉใƒณ้ธๆŠžใƒขใƒผใƒ€ใƒซ
    โ”‚       โ””โ”€โ”€ page.tsx               # (ไปปๆ„) ๅฐ‚็”จใฎ่ชฒ้‡‘ใƒšใƒผใ‚ธ
    โ””โ”€โ”€ lib/
        โ”œโ”€โ”€ api/
        โ”‚   โ””โ”€โ”€ dashboard.ts           # (ไปปๆ„) ใƒ€ใƒƒใ‚ทใƒฅใƒœใƒผใƒ‰APIใฎๅ‘ผใณๅ‡บใ—ใ‚’ใพใจใ‚ใŸ้–ขๆ•ฐ
        โ””โ”€โ”€ utils/
            โ””โ”€โ”€ dateUtils.ts           # (ไปปๆ„) date-fnsใ‚’ไฝฟใฃใŸๆ—ฅไป˜้–ข้€ฃใฎๅ…ฑ้€šใƒ˜ใƒซใƒ‘ใƒผ้–ขๆ•ฐ