feat: medication reminders, follow-up/visit separation, health record page
Backend: - MedicationService: today-summary with missed detection (local time) - FollowUpService: doctor-initiated follow-ups filter, AddAsync supports Notes - FollowUpController: type query param (followup/recheck) - MedicationController: today-summary endpoint - Auth: UpdateProfileRequest→class, StentDate/StentType, soft-delete fix Patient frontend: - HomePage: date display, medication reminder cards with missed status - MedicationListPage: beautified with delete button, slot preview - MedicationDetailPage: redesigned with progress bars, new CSS - ProfilePage: beautified menu icons, health record link - HealthRecordPage: new page with indicators, history, meds, reports - ServicesHub: added doctor-visit card - VisitListPage: doctor-initiated follow-ups view - EditProfilePage: removed height/weight, added stent fields - Fixed getProfile field mappings (nickname, height, weight, stent) Doctor frontend: - Layout: added 随访管理 sidebar item with SVG icon - FollowUpListPage: recheck-only filter, complete/delete buttons, collapsed completed - VisitListPage/EditPage: doctor follow-up management - PatientListPage: added stentType column - Dashboard: fixed pending reports endpoint - ReportListPage/DetailPage: fixed uploadedAt field - ChatPage: SignalR real-time, dynamic hostname
This commit is contained in:
191
frontend-patient/src/pages/profile/HealthRecordPage.module.css
Normal file
191
frontend-patient/src/pages/profile/HealthRecordPage.module.css
Normal file
@@ -0,0 +1,191 @@
|
||||
.profileCard {
|
||||
margin-bottom: 14px;
|
||||
padding: 18px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
width: 52px;
|
||||
height: 52px;
|
||||
border-radius: 16px;
|
||||
background: var(--color-primary-gradient);
|
||||
color: #fff;
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.profileInfo {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 17px;
|
||||
font-weight: 700;
|
||||
color: var(--color-text-primary);
|
||||
}
|
||||
|
||||
.phone {
|
||||
font-size: 13px;
|
||||
color: var(--color-text-tertiary);
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.arrow {
|
||||
font-size: 24px;
|
||||
color: var(--color-text-tertiary);
|
||||
}
|
||||
|
||||
.detailCard {
|
||||
margin-bottom: 14px;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.cardTitle {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: var(--color-text-primary);
|
||||
margin-bottom: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.cardTitle::before {
|
||||
content: '';
|
||||
width: 4px;
|
||||
height: 16px;
|
||||
border-radius: 2px;
|
||||
background: var(--color-primary);
|
||||
}
|
||||
|
||||
.cardCount {
|
||||
margin-left: auto;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: var(--color-text-tertiary);
|
||||
background: var(--color-bg);
|
||||
padding: 2px 10px;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.historyTags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.historyTag {
|
||||
padding: 5px 12px;
|
||||
border-radius: 20px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: var(--color-primary);
|
||||
background: var(--color-primary-bg);
|
||||
}
|
||||
|
||||
.stentInfo {
|
||||
margin-top: 12px;
|
||||
font-size: 13px;
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
|
||||
.indicatorsGrid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.indicatorItem {
|
||||
text-align: center;
|
||||
padding: 12px 8px;
|
||||
background: var(--color-bg);
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.indicatorValue {
|
||||
font-size: 20px;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.indicatorLabel {
|
||||
font-size: 12px;
|
||||
color: var(--color-text-secondary);
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.indicatorUnit {
|
||||
font-size: 10px;
|
||||
color: var(--color-text-tertiary);
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
.medItem {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 10px 0;
|
||||
border-bottom: 1px solid var(--color-divider);
|
||||
cursor: pointer;
|
||||
}
|
||||
.medItem:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.medName {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: var(--color-text-primary);
|
||||
}
|
||||
|
||||
.medMeta {
|
||||
font-size: 12px;
|
||||
color: var(--color-text-tertiary);
|
||||
}
|
||||
|
||||
.reportItem {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 10px 0;
|
||||
border-bottom: 1px solid var(--color-divider);
|
||||
cursor: pointer;
|
||||
}
|
||||
.reportItem:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.reportName {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: var(--color-text-primary);
|
||||
}
|
||||
|
||||
.reportStatus {
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
padding: 3px 10px;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.reportDone {
|
||||
background: var(--color-success-bg);
|
||||
color: #0D8A5E;
|
||||
}
|
||||
|
||||
.reportPending {
|
||||
background: var(--color-warning-bg);
|
||||
color: #D67E0B;
|
||||
}
|
||||
|
||||
.emptyText {
|
||||
text-align: center;
|
||||
padding: 16px;
|
||||
color: var(--color-text-tertiary);
|
||||
font-size: 13px;
|
||||
}
|
||||
Reference in New Issue
Block a user