first commit

This commit is contained in:
2025-03-03 20:59:42 +03:00
commit 273e68557a
1099 changed files with 17880 additions and 0 deletions

View File

@@ -0,0 +1,64 @@
// Flutter imports:
import 'package:flutter/material.dart';
import 'package:remever/common/resources.dart';
import 'package:remever/common/typography.dart';
import 'package:remever/components/extensions/context.dart';
class AuthTextField extends StatelessWidget {
const AuthTextField({required this.email, super.key, this.autofocus = true});
final TextEditingController email;
final bool autofocus;
@override
Widget build(BuildContext context) {
final OutlineInputBorder border = OutlineInputBorder(
borderRadius: const BorderRadius.all(Radius.circular(8)).r,
borderSide: BorderSide(color: AppColors.gray),
);
return TextFormField(
autofocus: autofocus,
controller: email,
validator: (String? value) {
if (value == null || value == '') return 'Поле не может быть пустым';
if (!value.contains('@') || !value.contains('.')) {
return 'Неверный e-mail';
}
return null;
},
cursorColor: AppColors.primary,
decoration: InputDecoration(
filled: true,
fillColor: AppColors.white,
focusedBorder: border,
enabledBorder: border,
errorBorder: border,
focusedErrorBorder: border,
hintText: 'Введите e-mail',
hintStyle: const TextStyle(fontWeight: FontWeight.w400, height: 1.2),
errorStyle: SemiBold12px().style.copyWith(color: AppColors.red),
suffixIconConstraints: const BoxConstraints(minWidth: 0, minHeight: 0),
suffixIcon: Padding(
padding: const EdgeInsets.only(right: 12).r,
child: InkWell(
onTap: () {
email.clear();
},
child: SizedBox.square(
dimension: 24.r,
child: DecoratedBox(
decoration: BoxDecoration(
color: AppColors.bg,
shape: BoxShape.circle,
),
child: Icon(Icons.close, color: AppColors.disabled, size: 16.r),
),
),
),
),
),
);
}
}

View File

@@ -0,0 +1,50 @@
// Flutter imports:
import 'package:flutter/material.dart';
import 'package:pin_code_fields/pin_code_fields.dart';
import 'package:remever/common/resources.dart';
import 'package:remever/components/extensions/context.dart';
class PinCode extends StatefulWidget {
const PinCode({super.key, required this.pinController});
final TextEditingController pinController;
@override
State<PinCode> createState() => _PinCodeState();
}
class _PinCodeState extends State<PinCode> {
@override
Widget build(BuildContext context) {
return PinCodeTextField(
controller: widget.pinController,
appContext: context,
length: 6,
keyboardType: TextInputType.number,
animationType: AnimationType.slide,
hapticFeedbackTypes: HapticFeedbackTypes.medium,
autoFocus: true,
enableActiveFill: true,
cursorColor: AppColors.primary,
validator: (value) {
if (value == null || value.isEmpty) return 'Поле не может быть пустым';
if (value.length < 5) return 'Слишком мало символов';
return null;
},
pinTheme: PinTheme(
fieldWidth: 48.w,
fieldHeight: 62.h,
borderRadius: BorderRadius.circular(8).r,
activeFillColor: AppColors.white,
selectedFillColor: AppColors.white,
inactiveColor: AppColors.white,
selectedColor: AppColors.white,
activeColor: AppColors.white,
shape: PinCodeFieldShape.box,
inactiveFillColor: AppColors.white,
),
onCompleted: (String value) async {},
);
}
}

View File

@@ -0,0 +1,95 @@
// Dart imports:
import 'dart:async';
// Flutter imports:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
// Package imports:
import 'package:provider/provider.dart';
import 'package:remever/common/resources.dart';
import 'package:remever/common/widgets/typography.dart';
import 'package:remever/common/widgets/w_if.dart';
import 'package:remever/common/widgets/wspace.dart';
import 'package:remever/components/extensions/context.dart';
import 'package:remever/components/extensions/state.dart';
class ResendTimer extends StatefulWidget {
const ResendTimer({required this.onTap, super.key});
final Function() onTap;
@override
State<ResendTimer> createState() => _ResendTimerState();
}
class _ResendTimerState extends State<ResendTimer> {
Timer? _timer;
int _start = 60;
void _startTimer() {
const Duration oneSec = Duration(seconds: 1);
_timer = Timer.periodic(oneSec, (Timer timer) {
if (_start > 0) {
safeSetState(() {
_start--;
});
} else {
_timer?.cancel();
}
});
}
@override
void initState() {
_startTimer();
super.initState();
}
@override
void dispose() {
_timer?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Wif(
condition: _start == 0,
builder: (BuildContext context) => _buildResend(),
fallback: (BuildContext context) => _buildTimer(),
);
}
Widget _buildResend() {
return InkWell(
onTap: () async {
await widget.onTap();
safeSetState(() => _start = 60);
_startTimer();
},
child: AppTypography(
'Получить новый код на e-mail',
type: Regular14px(),
color: AppColors.primary,
),
);
}
Widget _buildTimer() {
return Row(
children: <Widget>[
AppTypography(
'Получить новый код можно будет через: ',
type: Regular14px(),
color: AppColors.disabled,
),
AppTypography(
'$_start сек',
type: Regular14px(),
color: AppColors.disabled,
),
],
);
}
}