feat: Add Nanaxe server with Docker, GitHub Actions CI/CD, and auto-deployment

- Add complete server infrastructure with Gitea, API, PostgreSQL
- Implement Obsidian-compatible markdown mindmap converter
- Add Flutter service for server synchronization
- Configure GitHub Actions for automated build and deploy
- Add production docker-compose with health checks
- Include VPS setup and deployment scripts
- Add comprehensive deployment documentation
This commit is contained in:
2026-04-19 22:18:25 +05:00
parent 52aea9ac87
commit f1e0f6b5ef
56 changed files with 8892 additions and 397 deletions
+8 -9
View File
@@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:table_calendar/table_calendar.dart';
import '../models/calendar_event_model.dart';
import '../core/google_calendar_service.dart';
class CalendarScreen extends ConsumerStatefulWidget {
const CalendarScreen({super.key});
@@ -267,8 +266,8 @@ class _CalendarScreenState extends ConsumerState<CalendarScreen> {
final descriptionController = TextEditingController();
final locationController = TextEditingController();
TimeOfDay _startTime = const TimeOfDay(hour: 10, minute: 0);
TimeOfDay _endTime = const TimeOfDay(hour: 11, minute: 0);
TimeOfDay startTime = const TimeOfDay(hour: 10, minute: 0);
TimeOfDay endTime = const TimeOfDay(hour: 11, minute: 0);
showDialog(
context: context,
@@ -312,16 +311,16 @@ class _CalendarScreenState extends ConsumerState<CalendarScreen> {
Expanded(
child: ListTile(
title: const Text('Начало'),
subtitle: Text(_startTime.format(context)),
subtitle: Text(startTime.format(context)),
leading: const Icon(Icons.access_time),
onTap: () async {
final picked = await showTimePicker(
context: context,
initialTime: _startTime,
initialTime: startTime,
);
if (picked != null) {
setDialogState(() {
_startTime = picked;
startTime = picked;
});
}
},
@@ -330,16 +329,16 @@ class _CalendarScreenState extends ConsumerState<CalendarScreen> {
Expanded(
child: ListTile(
title: const Text('Конец'),
subtitle: Text(_endTime.format(context)),
subtitle: Text(endTime.format(context)),
leading: const Icon(Icons.access_time),
onTap: () async {
final picked = await showTimePicker(
context: context,
initialTime: _endTime,
initialTime: endTime,
);
if (picked != null) {
setDialogState(() {
_endTime = picked;
endTime = picked;
});
}
},