glanzlicht / Meinweimar_Saving_App

MW Rettertuete & Deals - clean

Verified secure showcase
112 Files 341 KB Public size 7 Redacted Dart · XCCONFIG · H · XML · GITIGNORE · PLIST

Project overview

Meinweimar_Saving_App is a verified code showcase with 112 visible project entries across 9 top-level modules. The primary detected language is Dart; protected files remain visible in the structure while their contents stay private.

README

meinweimar_box__nativ

A new Flutter project.

Getting Started

This project is a starting point for a Flutter application.

A few resources to get you started if this is your first Flutter project:

For help getting started with Flutter development, view the online documentation, which offers tutorials, samples, guidance on mobile development, and a full API reference.

lib/profile_page.dartDart
import 'dart:convert';
import 'constants.dart';
import 'core/api/api_endpoints.dart';
import 'core/api/auth_headers.dart';
import 'core/prefs/pref_keys.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';
// Importiert alles Wichtige aus der main.dart
import 'main.dart';
// Importiert die LoginPage für den Logout
import 'login_page.dart';
class NativeProfilePage extends StatefulWidget {
const NativeProfilePage({super.key});
@override State<NativeProfilePage> createState() => _NativeProfilePageState();
}
class _NativeProfilePageState extends State<NativeProfilePage> {
final _name = TextEditingController(); final _email = TextEditingController();
final _fName = TextEditingController(); final _lName = TextEditingController();
final _addr = TextEditingController(); final _pc = TextEditingController();
final _city = TextEditingController(); final _phone = TextEditingController();
final _pw1 = TextEditingController(); final _pw2 = TextEditingController();
bool _loading = true;
bool _saving = false;
bool _showPw = false;
@override void initState() {
super.initState();
_fetch();
}
// Daten vom WordPress-Server laden
_fetch() async {
try {
final prefs = await SharedPreferences.getInstance();
final t = prefs.getString(PrefKeys.jwtToken);
final r = await http.get(
Uri.parse(ApiEndpoints.wpUsersMeEditContext),
headers: AuthHeaders.bearer('$t')
);
if (r.statusCode == 200) {
final d = json.decode(r.body);
final m = d['meta'] ?? {};
setState(() {
_name.text = d['name'] ?? "";
_email.text = d['email'] ?? "";
_fName.text = _gm(m, 'billing_first_name');
_lName.text = _gm(m, 'billing_last_name');
_addr.text = _gm(m, 'billing_address_1');
_pc.text = _gm(m, 'billing_postcode');
_city.text = _gm(m, 'billing_city');
_phone.text = _gm(m, 'billing_phone');
_loading = false;
});
} else {
// Falls der Token ungültig ist, ausloggen
_logout();
}
} catch (e) {
debugPrint("Fehler beim Laden: $e");
setState(() => _loading = false);
}
}
String _gm(dynamic m, String k) {
if (m[k] == null) return "";
return (m[k] is List && m[k].isNotEmpty) ? m[k][0].toString() : m[k].toString();
}
_save() async {
if (_showPw && (_pw1.text.isEmpty || _pw1.text != _pw2.text)) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text("Passwörter stimmen nicht überein!"), backgroundColor: Colors.orange)
);
return;
}
setState(() => _saving = true);
final t = (await SharedPreferences.getInstance()).getString(PrefKeys.jwtToken);
Map<String, dynamic> data = {
"name": _name.text,
"email": _email.text,
"meta": {
"billing_first_name": _fName.text,
"billing_last_name": _lName.text,
"billing_address_1": _addr.text,
"billing_postcode": _pc.text,
"billing_city": _city.text,
"billing_phone": _phone.text
}
};
if (_showPw && _pw1.text.isNotEmpty) data["password"] = _pw1.text;
final r = await http.post(
Uri.parse(ApiEndpoints.wpUsersMe),
headers: {...AuthHeaders.bearer('$t'), 'Content-Type': 'application/json'},
body: json.encode(data)
);
if (mounted) {
setState(() => _saving = false);
if (r.statusCode == 200) {
if (_showPw) {
final prefs = await SharedPreferences.getInstance();
await prefs.setString(PrefKeys.savedPassword, _pw1.text);
setState(() => _showPw = false);
_pw1.clear(); _pw2.clear();
}
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text("Gespeichert!"), backgroundColor: Colors.green)
);
}
}
}
_logout() async {
final prefs = await SharedPreferences.getInstance();
await prefs.remove(PrefKeys.jwtToken);
if (mounted) Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => const LoginPage()));
}
@override Widget build(BuildContext context) {
if (_loading) return const Scaffold(body: Center(child: CircularProgressIndicator(color: AppConstants.mainColor)));
return Scaffold(
backgroundColor: AppConstants.baseWhite,
appBar: AppBar(
title: const Text("Profil"),
backgroundColor: AppConstants.baseWhite,
foregroundColor: AppConstants.fontGrey,
elevation: 0,
actions: [IconButton(onPressed: _logout, icon: const Icon(Icons.logout))]
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(25),
child: Column(children: [
_in("Anzeigename", _name),
_in("E-Mail Adresse", _email),
Row(children: [
Expanded(child: _in("Vorname", _fName)),
const SizedBox(width: 10),
Expanded(child: _in("Nachname", _lName))
]),
_in("Straße & Hausnr.", _addr),
Row(children: [
Expanded(flex: 2, child: _in("PLZ", _pc)),
const SizedBox(width: 10),
Expanded(flex: 3, child: _in("Ort", _city))
]),
_in("Handynummer", _phone),
const Divider(height: 40),
if (!_showPw)
TextButton.icon(
onPressed: () => setState(() => _showPw = true),
icon: const Icon(Icons.lock_outline, color: AppConstants.mainColor),
label: const Text("Passwort ändern", style: TextStyle(color: AppConstants.mainColor, fontWeight: FontWeight.bold))
)
else ...[
const Text("Neues Passwort festlegen", style: TextStyle(fontWeight: FontWeight.bold, color: AppConstants.fontGrey)),
const SizedBox(height: 15),
_in("Neues Passwort", _pw1, obscure: true),
_in("Passwort wiederholen", _pw2, obscure: true),
TextButton(onPressed: () => setState(() => _showPw = false), child: const Text("Abbrechen", style: TextStyle(color: Colors.grey))),
],
const SizedBox(height: 20),
_saving
? const CircularProgressIndicator(color: AppConstants.mainColor)
: SizedBox(
width: double.infinity,
height: 55,
child: ElevatedButton(
onPressed: _save,
style: ElevatedButton.styleFrom(backgroundColor: AppConstants.mainColor),
child: const Text("ALLES SPEICHERN", style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold))
)
),
]),
),
);
}
Widget _in(String l, TextEditingController c, {bool obscure = false}) => Padding(
padding: const EdgeInsets.only(bottom: 12),
child: TextField(
controller: c,
obscureText: obscure,
decoration: InputDecoration(labelText: l, border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)))
)
);
}

Architecture

High-level modules detected from the verified public snapshot. Protected implementation details are intentionally omitted.

macosmodule
iosmodule
libmodule
windowsmodule
androidmodule
linuxmodule
webmodule
testmodule

Technology stack

DartPBXPROJLOCKXIBTXTCPPFlutter / Dart
Dart39.9%
PBXPROJ16.4%
LOCK7.1%
XIB6.8%
TXT5.2%
CPP3.9%
JSON2.9%
XCSCHEME2.2%