Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions frontend/ongi/lib/models/temperature_contribution.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
class FamilyTemperatureContributionResponse {
final List<Contribution> contributions;

FamilyTemperatureContributionResponse({required this.contributions});

factory FamilyTemperatureContributionResponse.fromJson(Map<String, dynamic> json) {
var list = json['contributions'] as List<dynamic>? ?? [];
return FamilyTemperatureContributionResponse(
contributions: list.map((e) => Contribution.fromJson(e)).toList(),
);
}
}

class Contribution {
final DateTime dateTime;
final String userName;
final String reason;
final double contributed;

Contribution({
required this.dateTime,
required this.userName,
required this.reason,
required this.contributed,
});

factory Contribution.fromJson(Map<String, dynamic> json) {
return Contribution(
dateTime: DateTime.parse(json['dateTime']),
userName: json['userName'] ?? '',
reason: json['reason'] ?? '',
contributed: (json['contributed'] as num?)?.toDouble() ?? 0.0,
);
}

String get formattedDate => '${dateTime.year % 100}.${dateTime.month.toString().padLeft(2, '0')}.${dateTime.day.toString().padLeft(2, '0')} '
'${dateTime.hour.toString().padLeft(2, '0')}:${dateTime.minute.toString().padLeft(2, '0')}';

String get formattedChange => (contributed > 0 ? '+' : '') + contributed.toStringAsFixed(1) + '°C';
}
18 changes: 10 additions & 8 deletions frontend/ongi/lib/screens/home/home_degree_graph.dart
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,10 @@ class _HomeDegreeGraph extends State<HomeDegreeGraph> {
sideTitles: SideTitles(
showTitles: true,
getTitlesWidget: (value, meta) {
int idx = value.round();
if (idx < 0 || idx >= dates.length) return const SizedBox.shrink();
if (value % 1 != 0) return const SizedBox.shrink();
int idx = value.toInt();
if (idx < 0 || idx >= dates.length)
return const SizedBox.shrink();
return Padding(
padding: const EdgeInsets.only(top: 8),
child: Text(
Expand Down Expand Up @@ -276,12 +278,13 @@ class _HomeDegreeGraph extends State<HomeDegreeGraph> {
SizedBox(
height: 290,
child: ListView.builder(
itemCount: contributions.length,
itemCount: history.length,
itemBuilder: (context, idx) {
final item = contributions[idx];
final item = history[idx];
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 왼쪽 선과 원
Column(
children: [
Container(
Expand All @@ -293,14 +296,14 @@ class _HomeDegreeGraph extends State<HomeDegreeGraph> {
color: Colors.white,
),
),
if (idx != contributions.length - 1)
if (idx != history.length - 1)
Container(width: 2, height: 24, color: Colors.orange),
],
),
const SizedBox(width: 8),
Expanded(
child: Text(
"${item.userName}이 ${item.formattedChange} 상승 시켰어요!",
"${item['name']}이 ${item['change']} 상승 시켰어요!",
style: const TextStyle(
color: Colors.grey,
fontSize: 15,
Expand All @@ -309,7 +312,7 @@ class _HomeDegreeGraph extends State<HomeDegreeGraph> {
),
),
Text(
item.formattedDate,
item['date'] ?? '',
style: const TextStyle(
color: Colors.grey,
fontSize: 12,
Expand All @@ -325,4 +328,3 @@ class _HomeDegreeGraph extends State<HomeDegreeGraph> {
);
}
}

41 changes: 41 additions & 0 deletions frontend/ongi/lib/services/temperature_service.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import 'dart:convert';
import 'package:http/http.dart' as http;

class TemperatureService {
final String baseUrl;
TemperatureService({required this.baseUrl});

Future<List<Map<String, dynamic>>> fetchFamilyTemperatureDaily(String familyCode, {String? token}) async {
final url = Uri.parse('$baseUrl/temperature/daily?familyId=$familyCode');
Map<String, String> headers = {
'Content-Type': 'application/json',
};
if (token != null) {
headers['Authorization'] = 'Bearer $token';
}
final response = await http.get(url, headers: headers);
if (response.statusCode == 200) {
final data = json.decode(response.body);
return List<Map<String, dynamic>>.from(data['dailyTemperatures'] ?? data ?? []);
} else {
throw Exception('가족 온도 일별 데이터 불러오기 실패');
}
}

Future<List<dynamic>> fetchFamilyTemperatureContributions(String familyCode, {String? token}) async {
final url = Uri.parse('$baseUrl/temperature/contributions?familyId=$familyCode');
Map<String, String> headers = {
'Content-Type': 'application/json',
};
if (token != null) {
headers['Authorization'] = 'Bearer $token';
}
final response = await http.get(url, headers: headers);
if (response.statusCode == 200) {
final data = json.decode(response.body);
return data['contributions'] ?? data ?? [];
} else {
throw Exception('가족 온도 기여도 데이터 불러오기 실패');
}
}
}
Loading