creek

The AI Image Editor of 2030

lib/ui/widgets/note_input_sheet.dart (6737B)


  1import 'package:flutter/material.dart';
  2import 'package:shared_preferences/shared_preferences.dart';
  3import 'package:creekui/ui/styles/variables.dart';
  4
  5class NoteInputSheet extends StatefulWidget {
  6  final List<String> categories;
  7  final String initialCategory;
  8  final Function(String content, String category) onSubmit;
  9
 10  const NoteInputSheet({
 11    super.key,
 12    required this.categories,
 13    required this.initialCategory,
 14    required this.onSubmit,
 15  });
 16
 17  @override
 18  State<NoteInputSheet> createState() => _NoteInputSheetState();
 19}
 20
 21class _NoteInputSheetState extends State<NoteInputSheet> {
 22  late String _selectedCategory;
 23  final TextEditingController _controller = TextEditingController();
 24  String _userName = "Alex"; // Default
 25
 26  @override
 27  void initState() {
 28    super.initState();
 29    _selectedCategory = widget.initialCategory;
 30    _loadUserName();
 31  }
 32
 33  Future<void> _loadUserName() async {
 34    final prefs = await SharedPreferences.getInstance();
 35    if (mounted) {
 36      setState(() {
 37        _userName = prefs.getString('user_name') ?? "Alex";
 38      });
 39    }
 40  }
 41
 42  @override
 43  void dispose() {
 44    _controller.dispose();
 45    super.dispose();
 46  }
 47
 48  @override
 49  Widget build(BuildContext context) {
 50    return Padding(
 51      padding: const EdgeInsets.all(16),
 52      child: Column(
 53        mainAxisSize: MainAxisSize.min,
 54        children: [
 55          // Header Row
 56          Row(
 57            children: [
 58              Container(
 59                width: 30,
 60                height: 30,
 61                decoration: BoxDecoration(
 62                  shape: BoxShape.circle,
 63                  border: Border.all(
 64                    color: Variables.surfaceBackground,
 65                    width: 1.25,
 66                  ),
 67                ),
 68                child: const CircleAvatar(
 69                  radius: 15,
 70                  backgroundColor: Colors.grey,
 71                  child: Icon(Icons.person, color: Colors.white, size: 18),
 72                ),
 73              ),
 74              const SizedBox(width: 10),
 75              Text(
 76                _userName,
 77                style: Variables.bodyStyle.copyWith(
 78                  fontSize: 12,
 79                  fontWeight: FontWeight.w500,
 80                ),
 81              ),
 82              const Spacer(),
 83              Container(
 84                padding: const EdgeInsets.symmetric(
 85                  horizontal: 12,
 86                  vertical: 6,
 87                ),
 88                decoration: BoxDecoration(
 89                  color: Variables.chipBackground,
 90                  borderRadius: BorderRadius.circular(1000),
 91                ),
 92                child: DropdownButtonHideUnderline(
 93                  child: DropdownButton<String>(
 94                    value:
 95                        widget.categories.contains(_selectedCategory)
 96                            ? _selectedCategory
 97                            : null,
 98                    hint: Text(
 99                      "Type",
100                      style: Variables.bodyStyle.copyWith(fontSize: 12),
101                    ),
102                    isDense: true,
103                    icon: const Icon(
104                      Icons.arrow_drop_down,
105                      size: 20,
106                      color: Variables.textPrimary,
107                    ),
108                    style: Variables.bodyStyle.copyWith(fontSize: 12),
109                    dropdownColor: Colors.white,
110                    items:
111                        widget.categories
112                            .map(
113                              (c) => DropdownMenuItem(value: c, child: Text(c)),
114                            )
115                            .toList(),
116                    onChanged: (v) {
117                      if (v != null) setState(() => _selectedCategory = v);
118                    },
119                  ),
120                ),
121              ),
122            ],
123          ),
124          const SizedBox(height: 16),
125          // Input Row
126          Row(
127            crossAxisAlignment: CrossAxisAlignment.end,
128            children: [
129              Expanded(
130                child: Container(
131                  decoration: BoxDecoration(
132                    color: Variables.surfaceSubtle,
133                    border: Border.all(color: Variables.borderSubtle),
134                    borderRadius: BorderRadius.circular(8),
135                  ),
136                  child: TextField(
137                    controller: _controller,
138                    autofocus: true,
139                    maxLines: null,
140                    style: Variables.bodyStyle.copyWith(fontSize: 12),
141                    decoration: const InputDecoration(
142                      hintText: "Enter note details...",
143                      border: InputBorder.none,
144                      contentPadding: EdgeInsets.symmetric(
145                        horizontal: 12,
146                        vertical: 10,
147                      ),
148                    ),
149                  ),
150                ),
151              ),
152              const SizedBox(width: 8),
153              IconButton(
154                icon: const Icon(
155                  Icons.send,
156                  color: Variables.textPrimary,
157                  size: 24,
158                ),
159                onPressed: () {
160                  if (_controller.text.isNotEmpty) {
161                    widget.onSubmit(_controller.text.trim(), _selectedCategory);
162                  }
163                },
164                padding: EdgeInsets.zero,
165                constraints: const BoxConstraints(minWidth: 24, minHeight: 24),
166              ),
167            ],
168          ),
169          const SizedBox(height: 10),
170        ],
171      ),
172    );
173  }
174}
175
176class NoteModalOverlay extends StatelessWidget {
177  final Widget modalContent;
178  final Size screenSize;
179
180  const NoteModalOverlay({
181    super.key,
182    required this.modalContent,
183    required this.screenSize,
184  });
185
186  @override
187  Widget build(BuildContext context) {
188    final mq = MediaQuery.of(context);
189    return Align(
190      alignment: Alignment.bottomCenter,
191      child: AnimatedPadding(
192        duration: const Duration(milliseconds: 250),
193        curve: Curves.easeOut,
194        padding: EdgeInsets.only(bottom: mq.viewInsets.bottom),
195        child: ConstrainedBox(
196          constraints: BoxConstraints(maxHeight: screenSize.height),
197          child: Material(
198            color: Colors.white,
199            elevation: 10,
200            shadowColor: Colors.black26,
201            borderRadius: const BorderRadius.vertical(top: Radius.circular(20)),
202            clipBehavior: Clip.antiAlias,
203            child: SingleChildScrollView(
204              padding: EdgeInsets.only(bottom: mq.padding.bottom),
205              child: modalContent,
206            ),
207          ),
208        ),
209      ),
210    );
211  }
212}