horecagelegenheidoverzicht_kaart_widget.dart 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514
  1. import '/flutter_flow/flutter_flow_icon_button.dart';
  2. import '/flutter_flow/flutter_flow_theme.dart';
  3. import '/flutter_flow/flutter_flow_util.dart';
  4. import '/flutter_flow/flutter_flow_widgets.dart';
  5. import 'dart:ui';
  6. import '/custom_code/actions/index.dart' as actions;
  7. import '/flutter_flow/custom_functions.dart' as functions;
  8. import 'package:aligned_tooltip/aligned_tooltip.dart';
  9. import 'package:cached_network_image/cached_network_image.dart';
  10. import 'package:flutter/material.dart';
  11. import 'package:flutter_blurhash/flutter_blurhash.dart';
  12. import 'package:flutter_spinkit/flutter_spinkit.dart';
  13. import 'package:google_fonts/google_fonts.dart';
  14. import 'package:octo_image/octo_image.dart';
  15. import 'package:provider/provider.dart';
  16. import 'horecagelegenheidoverzicht_kaart_model.dart';
  17. export 'horecagelegenheidoverzicht_kaart_model.dart';
  18. /// Create a component with a card overview of cards with the following data;
  19. /// {
  20. /// "nid": "75618",
  21. /// "titel": "Hof van Cartesius",
  22. /// "adres": "Vlampijpstraat 84-94\n",
  23. /// "plaats": "Utrecht (stad)",
  24. /// "logo":
  25. /// "https://uitgaanskrant.com/sites/uitgaanskrant.com/files/car.jpg",
  26. /// "categorie": [
  27. /// "Ondernemen",
  28. /// "Zaalverhuur"
  29. /// ]
  30. /// },
  31. /// i retrieve it with an api call named; Establishments
  32. ///
  33. /// The cards have a logo on the left and the details on the rigth of the
  34. /// card.
  35. ///
  36. /// Only show max 3 categorie items. Put points behind the last to expand all
  37. /// the categories.
  38. /// The categories are shown as buttons (containers) on the logo picture.
  39. class HorecagelegenheidoverzichtKaartWidget extends StatefulWidget {
  40. const HorecagelegenheidoverzichtKaartWidget({
  41. super.key,
  42. this.titel,
  43. this.logo,
  44. this.nid,
  45. this.adres,
  46. this.plaats,
  47. this.categorie,
  48. });
  49. final String? titel;
  50. final String? logo;
  51. final String? nid;
  52. final String? adres;
  53. final String? plaats;
  54. final List<String>? categorie;
  55. @override
  56. State<HorecagelegenheidoverzichtKaartWidget> createState() =>
  57. _HorecagelegenheidoverzichtKaartWidgetState();
  58. }
  59. class _HorecagelegenheidoverzichtKaartWidgetState
  60. extends State<HorecagelegenheidoverzichtKaartWidget> with RouteAware {
  61. late HorecagelegenheidoverzichtKaartModel _model;
  62. @override
  63. void setState(VoidCallback callback) {
  64. super.setState(callback);
  65. _model.onUpdate();
  66. }
  67. @override
  68. void initState() {
  69. super.initState();
  70. _model = createModel(context, () => HorecagelegenheidoverzichtKaartModel());
  71. }
  72. @override
  73. void dispose() {
  74. routeObserver.unsubscribe(this);
  75. _model.maybeDispose();
  76. super.dispose();
  77. }
  78. @override
  79. void didUpdateWidget(HorecagelegenheidoverzichtKaartWidget oldWidget) {
  80. super.didUpdateWidget(oldWidget);
  81. _model.widget = widget;
  82. }
  83. @override
  84. void didChangeDependencies() {
  85. super.didChangeDependencies();
  86. final route = DebugModalRoute.of(context);
  87. if (route != null) {
  88. routeObserver.subscribe(this, route);
  89. }
  90. debugLogGlobalProperty(context);
  91. }
  92. @override
  93. void didPopNext() {
  94. if (mounted && DebugFlutterFlowModelContext.maybeOf(context) == null) {
  95. setState(() => _model.isRouteVisible = true);
  96. debugLogWidgetClass(_model);
  97. }
  98. }
  99. @override
  100. void didPush() {
  101. if (mounted && DebugFlutterFlowModelContext.maybeOf(context) == null) {
  102. setState(() => _model.isRouteVisible = true);
  103. debugLogWidgetClass(_model);
  104. }
  105. }
  106. @override
  107. void didPop() {
  108. _model.isRouteVisible = false;
  109. }
  110. @override
  111. void didPushNext() {
  112. _model.isRouteVisible = false;
  113. }
  114. @override
  115. Widget build(BuildContext context) {
  116. DebugFlutterFlowModelContext.maybeOf(context)
  117. ?.parentModelCallback
  118. ?.call(_model);
  119. context.watch<FFAppState>();
  120. return Padding(
  121. padding: EdgeInsetsDirectional.fromSTEB(16.0, 16.0, 16.0, 16.0),
  122. child: Container(
  123. decoration: BoxDecoration(
  124. color: FlutterFlowTheme.of(context).secondaryBackground,
  125. boxShadow: [
  126. BoxShadow(
  127. blurRadius: 4.0,
  128. color: Color(0x33000000),
  129. offset: Offset(
  130. 0.0,
  131. 2.0,
  132. ),
  133. spreadRadius: 0.0,
  134. )
  135. ],
  136. borderRadius: BorderRadius.circular(12.0),
  137. ),
  138. child: Padding(
  139. padding: EdgeInsets.all(12.0),
  140. child: Row(
  141. mainAxisSize: MainAxisSize.max,
  142. children: [
  143. Flexible(
  144. child: Align(
  145. alignment: AlignmentDirectional(-1.0, 1.0),
  146. child: Stack(
  147. alignment: AlignmentDirectional(-1.0, 1.0),
  148. children: [
  149. Builder(
  150. builder: (context) {
  151. if ((widget!.logo != '') &&
  152. (widget!.logo != null && widget!.logo != '')) {
  153. return ClipRRect(
  154. borderRadius: BorderRadius.circular(8.0),
  155. child: OctoImage(
  156. placeholderBuilder: (_) => SizedBox.expand(
  157. child: Image(
  158. image: BlurHashImage(
  159. 'L6PZfSi_.AyE_3t7t7R**0o#DgR4'),
  160. fit: BoxFit.cover,
  161. ),
  162. ),
  163. image: CachedNetworkImageProvider(
  164. widget!.logo!,
  165. ),
  166. width: 100.0,
  167. height: 100.0,
  168. fit: BoxFit.cover,
  169. ),
  170. );
  171. } else {
  172. return Icon(
  173. Icons.image_not_supported,
  174. color: FlutterFlowTheme.of(context).primaryText,
  175. size: 24.0,
  176. );
  177. }
  178. },
  179. ),
  180. Align(
  181. alignment: AlignmentDirectional(-1.0, 1.0),
  182. child: Container(
  183. decoration: BoxDecoration(
  184. color: Color(0x40000000),
  185. ),
  186. child: Padding(
  187. padding: EdgeInsetsDirectional.fromSTEB(
  188. 8.0, 0.0, 8.0, 0.0),
  189. child: Builder(
  190. builder: (context) {
  191. final categorie =
  192. (widget!.categorie?.toList() ?? [])
  193. .take(3)
  194. .toList();
  195. _model.debugGeneratorVariables[
  196. 'categorie${categorie.length > 100 ? ' (first 100)' : ''}'] =
  197. debugSerializeParam(
  198. categorie.take(100),
  199. ParamType.String,
  200. isList: true,
  201. link:
  202. 'https://app.flutterflow.io/project/uitgaanskrant-1qhvtd?tab=uiBuilder&page=HorecagelegenheidoverzichtKaart',
  203. name: 'String',
  204. nullable: false,
  205. );
  206. debugLogWidgetClass(_model);
  207. return Column(
  208. mainAxisSize: MainAxisSize.min,
  209. mainAxisAlignment: MainAxisAlignment.end,
  210. crossAxisAlignment: CrossAxisAlignment.start,
  211. children: List.generate(categorie.length,
  212. (categorieIndex) {
  213. final categorieItem =
  214. categorie[categorieIndex];
  215. return Align(
  216. alignment:
  217. AlignmentDirectional(-1.0, 1.0),
  218. child: Container(
  219. decoration: BoxDecoration(),
  220. alignment:
  221. AlignmentDirectional(-1.0, 1.0),
  222. child: Padding(
  223. padding:
  224. EdgeInsetsDirectional.fromSTEB(
  225. 6.0, 0.0, 6.0, 0.0),
  226. child: Container(
  227. decoration: BoxDecoration(
  228. color: Color(0xFF09B34A),
  229. borderRadius:
  230. BorderRadius.circular(12.0),
  231. ),
  232. child: Padding(
  233. padding: EdgeInsets.all(8.0),
  234. child: Text(
  235. categorieItem,
  236. style:
  237. FlutterFlowTheme.of(context)
  238. .labelSmall
  239. .override(
  240. font:
  241. GoogleFonts.inter(
  242. fontWeight:
  243. FlutterFlowTheme.of(
  244. context)
  245. .labelSmall
  246. .fontWeight,
  247. fontStyle:
  248. FlutterFlowTheme.of(
  249. context)
  250. .labelSmall
  251. .fontStyle,
  252. ),
  253. color: Colors.white,
  254. fontSize: 10.0,
  255. letterSpacing: 0.0,
  256. fontWeight:
  257. FlutterFlowTheme.of(
  258. context)
  259. .labelSmall
  260. .fontWeight,
  261. fontStyle:
  262. FlutterFlowTheme.of(
  263. context)
  264. .labelSmall
  265. .fontStyle,
  266. ),
  267. ),
  268. ),
  269. ),
  270. ),
  271. ),
  272. );
  273. }).divide(SizedBox(height: 4.0)),
  274. );
  275. },
  276. ),
  277. ),
  278. ),
  279. ),
  280. Align(
  281. alignment: AlignmentDirectional(1.0, -1.0),
  282. child: AlignedTooltip(
  283. content: Padding(
  284. padding: EdgeInsets.all(4.0),
  285. child: Text(
  286. FFLocalizations.of(context).getText(
  287. 'ujd0p09x' /* MessageFavoriet... */,
  288. ),
  289. style: FlutterFlowTheme.of(context)
  290. .bodyLarge
  291. .override(
  292. font: GoogleFonts.inter(
  293. fontWeight: FlutterFlowTheme.of(context)
  294. .bodyLarge
  295. .fontWeight,
  296. fontStyle: FlutterFlowTheme.of(context)
  297. .bodyLarge
  298. .fontStyle,
  299. ),
  300. letterSpacing: 0.0,
  301. fontWeight: FlutterFlowTheme.of(context)
  302. .bodyLarge
  303. .fontWeight,
  304. fontStyle: FlutterFlowTheme.of(context)
  305. .bodyLarge
  306. .fontStyle,
  307. ),
  308. ),
  309. ),
  310. offset: 4.0,
  311. preferredDirection: AxisDirection.down,
  312. borderRadius: BorderRadius.circular(8.0),
  313. backgroundColor:
  314. FlutterFlowTheme.of(context).secondaryBackground,
  315. elevation: 4.0,
  316. tailBaseWidth: 24.0,
  317. tailLength: 12.0,
  318. waitDuration: Duration(milliseconds: 100),
  319. showDuration: Duration(milliseconds: 1500),
  320. triggerMode: TooltipTriggerMode.tap,
  321. child: Builder(
  322. builder: (context) {
  323. if (FFAppState()
  324. .favorieteHorecaNids
  325. .contains(widget!.nid)) {
  326. return FlutterFlowIconButton(
  327. borderRadius: 8.0,
  328. buttonSize: 32.0,
  329. fillColor: Colors.white,
  330. icon: Icon(
  331. Icons.favorite,
  332. color: Color(0xFFB50808),
  333. size: 24.0,
  334. ),
  335. onPressed: () async {
  336. FFAppState().removeFromFavorieteHorecaNids(
  337. widget!.nid!);
  338. safeSetState(() {});
  339. await actions.drupalRequest(
  340. 'POST',
  341. 'https://uitgaanskrant.com/nl/flutterdrup/favorieten/unflag.json',
  342. FFAppState().userSessionname,
  343. FFAppState().userSessionid,
  344. FFAppState().userToken,
  345. functions
  346. .favorietenBodyNode(widget!.nid!)!,
  347. );
  348. },
  349. );
  350. } else {
  351. return FlutterFlowIconButton(
  352. borderRadius: 8.0,
  353. buttonSize: 32.0,
  354. fillColor: Colors.white,
  355. icon: Icon(
  356. Icons.favorite_border,
  357. color: Color(0xFFB50808),
  358. size: 24.0,
  359. ),
  360. onPressed: () async {
  361. FFAppState()
  362. .addToFavorieteHorecaNids(widget!.nid!);
  363. safeSetState(() {});
  364. await actions.drupalRequest(
  365. 'POST',
  366. 'https://uitgaanskrant.com/nl/flutterdrup/favorieten/flag.json',
  367. FFAppState().userSessionname,
  368. FFAppState().userSessionid,
  369. FFAppState().userToken,
  370. functions
  371. .favorietenBodyNode(widget!.nid!)!,
  372. );
  373. },
  374. );
  375. }
  376. },
  377. ),
  378. ),
  379. ),
  380. ],
  381. ),
  382. ),
  383. ),
  384. Expanded(
  385. child: Container(
  386. width: () {
  387. if (MediaQuery.sizeOf(context).width < kBreakpointSmall) {
  388. return 200.0;
  389. } else if (MediaQuery.sizeOf(context).width <
  390. kBreakpointMedium) {
  391. return 250.0;
  392. } else if (MediaQuery.sizeOf(context).width <
  393. kBreakpointLarge) {
  394. return 300.0;
  395. } else {
  396. return 350.0;
  397. }
  398. }(),
  399. decoration: BoxDecoration(),
  400. child: Column(
  401. mainAxisSize: MainAxisSize.min,
  402. mainAxisAlignment: MainAxisAlignment.start,
  403. crossAxisAlignment: CrossAxisAlignment.start,
  404. children: [
  405. Text(
  406. valueOrDefault<String>(
  407. widget!.titel,
  408. 'Titel onbekend',
  409. ),
  410. maxLines: 2,
  411. style:
  412. FlutterFlowTheme.of(context).titleMedium.override(
  413. font: GoogleFonts.interTight(
  414. fontWeight: FontWeight.w600,
  415. fontStyle: FlutterFlowTheme.of(context)
  416. .titleMedium
  417. .fontStyle,
  418. ),
  419. letterSpacing: 0.0,
  420. fontWeight: FontWeight.w600,
  421. fontStyle: FlutterFlowTheme.of(context)
  422. .titleMedium
  423. .fontStyle,
  424. ),
  425. ),
  426. Column(
  427. mainAxisSize: MainAxisSize.min,
  428. crossAxisAlignment: CrossAxisAlignment.start,
  429. children: [
  430. Text(
  431. valueOrDefault<String>(
  432. widget!.adres,
  433. 'Adres onbekend',
  434. ),
  435. style: FlutterFlowTheme.of(context)
  436. .bodyMedium
  437. .override(
  438. font: GoogleFonts.inter(
  439. fontWeight: FlutterFlowTheme.of(context)
  440. .bodyMedium
  441. .fontWeight,
  442. fontStyle: FlutterFlowTheme.of(context)
  443. .bodyMedium
  444. .fontStyle,
  445. ),
  446. color: FlutterFlowTheme.of(context)
  447. .secondaryText,
  448. letterSpacing: 0.0,
  449. fontWeight: FlutterFlowTheme.of(context)
  450. .bodyMedium
  451. .fontWeight,
  452. fontStyle: FlutterFlowTheme.of(context)
  453. .bodyMedium
  454. .fontStyle,
  455. ),
  456. ),
  457. Text(
  458. valueOrDefault<String>(
  459. widget!.plaats,
  460. 'Plaats onbekend',
  461. ),
  462. style: FlutterFlowTheme.of(context)
  463. .bodyMedium
  464. .override(
  465. font: GoogleFonts.inter(
  466. fontWeight: FlutterFlowTheme.of(context)
  467. .bodyMedium
  468. .fontWeight,
  469. fontStyle: FlutterFlowTheme.of(context)
  470. .bodyMedium
  471. .fontStyle,
  472. ),
  473. color: FlutterFlowTheme.of(context)
  474. .secondaryText,
  475. letterSpacing: 0.0,
  476. fontWeight: FlutterFlowTheme.of(context)
  477. .bodyMedium
  478. .fontWeight,
  479. fontStyle: FlutterFlowTheme.of(context)
  480. .bodyMedium
  481. .fontStyle,
  482. ),
  483. ),
  484. ].divide(SizedBox(height: 4.0)),
  485. ),
  486. ].divide(SizedBox(height: 8.0)),
  487. ),
  488. ),
  489. ),
  490. ].divide(SizedBox(width: 16.0)),
  491. ),
  492. ),
  493. ),
  494. );
  495. }
  496. }