Compare commits
No commits in common. "57fa4dca3c0ee22ebb60565284b547cc0ec44c40" and "ed8cbef8fe680f8bb312aff4586bbd430d486c06" have entirely different histories.
57fa4dca3c
...
ed8cbef8fe
|
|
@ -8,17 +8,6 @@ import '../state/session_state.dart';
|
||||||
class SessionsScreen extends StatefulWidget {
|
class SessionsScreen extends StatefulWidget {
|
||||||
const SessionsScreen({super.key});
|
const SessionsScreen({super.key});
|
||||||
|
|
||||||
/// Formats API `expires_at` (UTC RFC3339) for the device local timezone.
|
|
||||||
static String formatExpiresAtLocal(Object? raw) {
|
|
||||||
if (raw == null) return '';
|
|
||||||
final parsed = DateTime.tryParse(raw.toString());
|
|
||||||
if (parsed == null) return raw.toString();
|
|
||||||
final local = parsed.toLocal();
|
|
||||||
String two(int n) => n.toString().padLeft(2, '0');
|
|
||||||
return '${local.year}-${two(local.month)}-${two(local.day)} '
|
|
||||||
'${two(local.hour)}:${two(local.minute)}';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<SessionsScreen> createState() => _SessionsScreenState();
|
State<SessionsScreen> createState() => _SessionsScreenState();
|
||||||
}
|
}
|
||||||
|
|
@ -115,10 +104,7 @@ class _SessionsScreenState extends State<SessionsScreen> {
|
||||||
s['is_current'] == true ? '이 기기 (현재)' : '세션 #${s['id']}',
|
s['is_current'] == true ? '이 기기 (현재)' : '세션 #${s['id']}',
|
||||||
style: theme.textTheme.titleSmall,
|
style: theme.textTheme.titleSmall,
|
||||||
),
|
),
|
||||||
subtitle: Text(
|
subtitle: Text('만료: ${s['expires_at'] ?? ''}', style: theme.textTheme.bodySmall),
|
||||||
'만료: ${SessionsScreen.formatExpiresAtLocal(s['expires_at'])}',
|
|
||||||
style: theme.textTheme.bodySmall,
|
|
||||||
),
|
|
||||||
trailing: IconButton(
|
trailing: IconButton(
|
||||||
tooltip: '세션 종료',
|
tooltip: '세션 종료',
|
||||||
icon: const Icon(Icons.logout),
|
icon: const Icon(Icons.logout),
|
||||||
|
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
|
||||||
import 'package:ykavu_mobile/screens/sessions_screen.dart';
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
test('formatExpiresAtLocal converts UTC Z to local wall clock', () {
|
|
||||||
// Fixed offset via DateTime.parse keeps instant; toLocal() uses test TZ.
|
|
||||||
final raw = '2026-09-02T09:06:45.137172Z';
|
|
||||||
final out = SessionsScreen.formatExpiresAtLocal(raw);
|
|
||||||
final expected = DateTime.parse(raw).toLocal();
|
|
||||||
final two = (int n) => n.toString().padLeft(2, '0');
|
|
||||||
expect(
|
|
||||||
out,
|
|
||||||
'${expected.year}-${two(expected.month)}-${two(expected.day)} '
|
|
||||||
'${two(expected.hour)}:${two(expected.minute)}',
|
|
||||||
);
|
|
||||||
expect(out.contains('T'), isFalse);
|
|
||||||
expect(out.endsWith('Z'), isFalse);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('formatExpiresAtLocal handles null and garbage', () {
|
|
||||||
expect(SessionsScreen.formatExpiresAtLocal(null), '');
|
|
||||||
expect(SessionsScreen.formatExpiresAtLocal('not-a-date'), 'not-a-date');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue