Login-Page für Newcomer + freigestelltes App-Icon im Hero
- icon_transparent.py: blauer Sky-Hintergrund per RGB-Schwelle entfernt
(b > 0.55, b > r+0.05 …), trimmt auf Content-Bbox
- AppIconHero.imageset mit dem freigestellten Icon
- LoginView komplett neu strukturiert als ScrollView:
- Hero: freigestelltes App-Icon (kein SF Symbol mehr) + Titel + Tagline
- Pitch-Karte: vier Feature-Highlights (Gassi-Tracking, Community,
Tagebuch, Giftköder-Alarm) für Leute, die banyaro nicht kennen
- "Schon angemeldet?"-Karte mit dem klassischen Login-Form
- "Neu hier?"-Karte mit kostenlos/DSGVO/DE-Hosting-Pitch und großem
Register-Button mit person.crop.circle.badge.plus-Icon
This commit is contained in:
parent
500a645bfd
commit
4ee84d5a1a
3 changed files with 123 additions and 38 deletions
21
BanYaroGo/Assets.xcassets/AppIconHero.imageset/Contents.json
vendored
Normal file
21
BanYaroGo/Assets.xcassets/AppIconHero.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "icon-hero.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
BIN
BanYaroGo/Assets.xcassets/AppIconHero.imageset/icon-hero.png
vendored
Normal file
BIN
BanYaroGo/Assets.xcassets/AppIconHero.imageset/icon-hero.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 MiB |
|
|
@ -7,42 +7,94 @@ struct LoginView: View {
|
|||
@State private var password = ""
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 24) {
|
||||
Spacer()
|
||||
ScrollView {
|
||||
VStack(spacing: 28) {
|
||||
hero
|
||||
pitch
|
||||
loginCard
|
||||
registerCard
|
||||
}
|
||||
.padding(.horizontal, 24)
|
||||
.padding(.vertical, 32)
|
||||
}
|
||||
.scrollDismissesKeyboard(.interactively)
|
||||
}
|
||||
|
||||
Image(systemName: "pawprint.fill")
|
||||
.font(.system(size: 80))
|
||||
.foregroundStyle(Color.accentColor)
|
||||
// MARK: - Hero
|
||||
|
||||
VStack(spacing: 6) {
|
||||
private var hero: some View {
|
||||
VStack(spacing: 12) {
|
||||
Image("AppIconHero")
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
.frame(height: 120)
|
||||
Text("Ban Yaro Go")
|
||||
.font(.largeTitle.bold())
|
||||
Text("Melde dich mit deinem banyaro-Account an.")
|
||||
Text("Die deutschsprachige Hunde-Plattform — jetzt mit nativem GPS-Tracking.")
|
||||
.font(.callout)
|
||||
.foregroundStyle(.secondary)
|
||||
.multilineTextAlignment(.center)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Pitch (für Neue)
|
||||
|
||||
private var pitch: some View {
|
||||
VStack(alignment: .leading, spacing: 14) {
|
||||
feature(icon: "map.fill", title: "Gassi-Touren aufzeichnen", subtitle: "GPS-Tracking auch im Hintergrund — mit Pause, Live Activity und HealthKit-Sync.")
|
||||
feature(icon: "person.2.fill", title: "Hunde-Community", subtitle: "Gassi-Treffen, Tierärzte und Orte in deiner Nähe.")
|
||||
feature(icon: "book.fill", title: "Tagebuch & Impfpass", subtitle: "Alles rund um deinen Hund an einem Ort.")
|
||||
feature(icon: "exclamationmark.shield.fill", title: "Giftköder-Alarm", subtitle: "Warnungen aus deiner Region direkt aufs iPhone.")
|
||||
}
|
||||
.padding(18)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.background(.background.secondary, in: RoundedRectangle(cornerRadius: 16))
|
||||
}
|
||||
|
||||
private func feature(icon: String, title: String, subtitle: String) -> some View {
|
||||
HStack(alignment: .top, spacing: 12) {
|
||||
Image(systemName: icon)
|
||||
.font(.title3)
|
||||
.foregroundStyle(Color.accentColor)
|
||||
.frame(width: 28)
|
||||
VStack(alignment: .leading, spacing: 2) {
|
||||
Text(title).font(.subheadline.bold())
|
||||
Text(subtitle)
|
||||
.font(.caption)
|
||||
.foregroundStyle(.secondary)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Login (für bestehende User)
|
||||
|
||||
private var loginCard: some View {
|
||||
VStack(spacing: 12) {
|
||||
HStack {
|
||||
Text("Schon angemeldet?")
|
||||
.font(.headline)
|
||||
Spacer()
|
||||
}
|
||||
|
||||
TextField("E-Mail", text: $email)
|
||||
.textContentType(.emailAddress)
|
||||
.keyboardType(.emailAddress)
|
||||
.textInputAutocapitalization(.never)
|
||||
.autocorrectionDisabled()
|
||||
.padding()
|
||||
.background(.background.secondary, in: RoundedRectangle(cornerRadius: 12))
|
||||
.background(.background, in: RoundedRectangle(cornerRadius: 12))
|
||||
|
||||
SecureField("Passwort", text: $password)
|
||||
.textContentType(.password)
|
||||
.padding()
|
||||
.background(.background.secondary, in: RoundedRectangle(cornerRadius: 12))
|
||||
}
|
||||
.background(.background, in: RoundedRectangle(cornerRadius: 12))
|
||||
|
||||
if let error = auth.errorMessage {
|
||||
Text(error)
|
||||
.font(.footnote)
|
||||
.foregroundStyle(.red)
|
||||
.multilineTextAlignment(.center)
|
||||
.frame(maxWidth: .infinity)
|
||||
}
|
||||
|
||||
Button {
|
||||
|
|
@ -65,31 +117,43 @@ struct LoginView: View {
|
|||
.background(Color.accentColor, in: RoundedRectangle(cornerRadius: 12))
|
||||
.foregroundStyle(.white)
|
||||
.disabled(auth.isLoggingIn || email.isEmpty || password.isEmpty)
|
||||
|
||||
registrationHint
|
||||
|
||||
Spacer()
|
||||
}
|
||||
.padding(.horizontal, 28)
|
||||
.padding(18)
|
||||
.background(.background.secondary, in: RoundedRectangle(cornerRadius: 16))
|
||||
}
|
||||
|
||||
private var registrationHint: some View {
|
||||
VStack(spacing: 6) {
|
||||
Text("Noch kein Account?")
|
||||
// MARK: - Register (für Neue)
|
||||
|
||||
private var registerCard: some View {
|
||||
VStack(spacing: 10) {
|
||||
Text("Neu hier?")
|
||||
.font(.headline)
|
||||
Text("banyaro.app ist **kostenlos**, **DSGVO-konform** und wird in Deutschland gehostet — kein App-Store-Konto nötig.")
|
||||
.font(.footnote)
|
||||
.foregroundStyle(.secondary)
|
||||
.multilineTextAlignment(.center)
|
||||
|
||||
if let url = URL(string: "https://banyaro.app/#settings?tab=register") {
|
||||
Link(destination: url) {
|
||||
HStack(spacing: 6) {
|
||||
Text("Kostenlos bei banyaro.app registrieren")
|
||||
.font(.footnote.bold())
|
||||
Image(systemName: "arrow.up.right.square")
|
||||
.font(.caption)
|
||||
HStack(spacing: 8) {
|
||||
Image(systemName: "person.crop.circle.badge.plus")
|
||||
Text("Kostenlos registrieren").bold()
|
||||
Image(systemName: "arrow.up.right")
|
||||
.font(.caption.bold())
|
||||
}
|
||||
.frame(maxWidth: .infinity, minHeight: 50)
|
||||
}
|
||||
.background(Color.accentColor.opacity(0.15), in: RoundedRectangle(cornerRadius: 12))
|
||||
.foregroundStyle(Color.accentColor)
|
||||
}
|
||||
|
||||
Text("Öffnet die Registrierung im Browser. Danach mit den neuen Zugangsdaten oben einloggen.")
|
||||
.font(.caption2)
|
||||
.foregroundStyle(.tertiary)
|
||||
.multilineTextAlignment(.center)
|
||||
}
|
||||
}
|
||||
.padding(18)
|
||||
.background(.background.secondary, in: RoundedRectangle(cornerRadius: 16))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue