horecagelegenheidoverzicht_kaart_widget.dart 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520
  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: (_) {
  157. final blurHash =
  158. 'L6PZfSi_.AyE_3t7t7R**0o#DgR4';
  159. if (!validateBlurhash(blurHash)) {
  160. return const SizedBox.shrink();
  161. }
  162. return SizedBox.expand(
  163. child: Image(
  164. image: BlurHashImage(blurHash),
  165. fit: BoxFit.cover,
  166. ),
  167. );
  168. },
  169. image: CachedNetworkImageProvider(
  170. widget!.logo!,
  171. ),
  172. width: 100.0,
  173. height: 100.0,
  174. fit: BoxFit.cover,
  175. ),
  176. );
  177. } else {
  178. return Icon(
  179. Icons.image_not_supported,
  180. color: FlutterFlowTheme.of(context).primaryText,
  181. size: 24.0,
  182. );
  183. }
  184. },
  185. ),
  186. Align(
  187. alignment: AlignmentDirectional(-1.0, 1.0),
  188. child: Container(
  189. decoration: BoxDecoration(
  190. color: Color(0x40000000),
  191. ),
  192. child: Padding(
  193. padding: EdgeInsetsDirectional.fromSTEB(
  194. 8.0, 0.0, 8.0, 0.0),
  195. child: Builder(
  196. builder: (context) {
  197. final categorie =
  198. (widget!.categorie?.toList() ?? [])
  199. .take(3)
  200. .toList();
  201. _model.debugGeneratorVariables[
  202. 'categorie${categorie.length > 100 ? ' (first 100)' : ''}'] =
  203. debugSerializeParam(
  204. categorie.take(100),
  205. ParamType.String,
  206. isList: true,
  207. link:
  208. 'https://app.flutterflow.io/project/uitgaanskrant-1qhvtd?tab=uiBuilder&page=HorecagelegenheidoverzichtKaart',
  209. name: 'String',
  210. nullable: false,
  211. );
  212. debugLogWidgetClass(_model);
  213. return Column(
  214. mainAxisSize: MainAxisSize.min,
  215. mainAxisAlignment: MainAxisAlignment.end,
  216. crossAxisAlignment: CrossAxisAlignment.start,
  217. children: List.generate(categorie.length,
  218. (categorieIndex) {
  219. final categorieItem =
  220. categorie[categorieIndex];
  221. return Align(
  222. alignment:
  223. AlignmentDirectional(-1.0, 1.0),
  224. child: Container(
  225. decoration: BoxDecoration(),
  226. alignment:
  227. AlignmentDirectional(-1.0, 1.0),
  228. child: Padding(
  229. padding:
  230. EdgeInsetsDirectional.fromSTEB(
  231. 6.0, 0.0, 6.0, 0.0),
  232. child: Container(
  233. decoration: BoxDecoration(
  234. color: Color(0xFF09B34A),
  235. borderRadius:
  236. BorderRadius.circular(12.0),
  237. ),
  238. child: Padding(
  239. padding: EdgeInsets.all(8.0),
  240. child: Text(
  241. categorieItem,
  242. style: FlutterFlowTheme.of(
  243. context)
  244. .labelSmall
  245. .override(
  246. font: GoogleFonts.roboto(
  247. fontWeight:
  248. FlutterFlowTheme.of(
  249. context)
  250. .labelSmall
  251. .fontWeight,
  252. fontStyle:
  253. FlutterFlowTheme.of(
  254. context)
  255. .labelSmall
  256. .fontStyle,
  257. ),
  258. color: Colors.white,
  259. fontSize: 10.0,
  260. letterSpacing: 0.0,
  261. fontWeight:
  262. FlutterFlowTheme.of(
  263. context)
  264. .labelSmall
  265. .fontWeight,
  266. fontStyle:
  267. FlutterFlowTheme.of(
  268. context)
  269. .labelSmall
  270. .fontStyle,
  271. ),
  272. ),
  273. ),
  274. ),
  275. ),
  276. ),
  277. );
  278. }).divide(SizedBox(height: 4.0)),
  279. );
  280. },
  281. ),
  282. ),
  283. ),
  284. ),
  285. Align(
  286. alignment: AlignmentDirectional(1.0, -1.0),
  287. child: AlignedTooltip(
  288. content: Padding(
  289. padding: EdgeInsets.all(4.0),
  290. child: Text(
  291. FFLocalizations.of(context).getText(
  292. 'y7slo4b4' /* MessageFavoriet... */,
  293. ),
  294. style: FlutterFlowTheme.of(context)
  295. .bodyLarge
  296. .override(
  297. font: GoogleFonts.roboto(
  298. fontWeight: FlutterFlowTheme.of(context)
  299. .bodyLarge
  300. .fontWeight,
  301. fontStyle: FlutterFlowTheme.of(context)
  302. .bodyLarge
  303. .fontStyle,
  304. ),
  305. letterSpacing: 0.0,
  306. fontWeight: FlutterFlowTheme.of(context)
  307. .bodyLarge
  308. .fontWeight,
  309. fontStyle: FlutterFlowTheme.of(context)
  310. .bodyLarge
  311. .fontStyle,
  312. ),
  313. ),
  314. ),
  315. offset: 4.0,
  316. preferredDirection: AxisDirection.down,
  317. borderRadius: BorderRadius.circular(8.0),
  318. backgroundColor:
  319. FlutterFlowTheme.of(context).secondaryBackground,
  320. elevation: 4.0,
  321. tailBaseWidth: 24.0,
  322. tailLength: 12.0,
  323. waitDuration: Duration(milliseconds: 100),
  324. showDuration: Duration(milliseconds: 1500),
  325. triggerMode: TooltipTriggerMode.tap,
  326. child: Builder(
  327. builder: (context) {
  328. if (FFAppState()
  329. .favorieteHorecaNids
  330. .contains(widget!.nid)) {
  331. return FlutterFlowIconButton(
  332. borderRadius: 8.0,
  333. buttonSize: 32.0,
  334. fillColor: Colors.white,
  335. icon: Icon(
  336. Icons.favorite,
  337. color: FlutterFlowTheme.of(context).primary,
  338. size: 24.0,
  339. ),
  340. onPressed: () async {
  341. FFAppState().removeFromFavorieteHorecaNids(
  342. widget!.nid!);
  343. safeSetState(() {});
  344. await actions.drupalRequest(
  345. 'POST',
  346. 'https://uitgaanskrant.com/nl/flutterdrup/favorieten/unflag.json',
  347. FFAppState().userSessionname,
  348. FFAppState().userSessionid,
  349. FFAppState().userToken,
  350. functions
  351. .favorietenBodyNode(widget!.nid!)!,
  352. );
  353. },
  354. );
  355. } else {
  356. return FlutterFlowIconButton(
  357. borderRadius: 8.0,
  358. buttonSize: 32.0,
  359. fillColor: Colors.white,
  360. icon: Icon(
  361. Icons.favorite_border,
  362. color: FlutterFlowTheme.of(context).primary,
  363. size: 24.0,
  364. ),
  365. onPressed: () async {
  366. FFAppState()
  367. .addToFavorieteHorecaNids(widget!.nid!);
  368. safeSetState(() {});
  369. await actions.drupalRequest(
  370. 'POST',
  371. 'https://uitgaanskrant.com/nl/flutterdrup/favorieten/flag.json',
  372. FFAppState().userSessionname,
  373. FFAppState().userSessionid,
  374. FFAppState().userToken,
  375. functions
  376. .favorietenBodyNode(widget!.nid!)!,
  377. );
  378. },
  379. );
  380. }
  381. },
  382. ),
  383. ),
  384. ),
  385. ],
  386. ),
  387. ),
  388. ),
  389. Expanded(
  390. child: Container(
  391. width: () {
  392. if (MediaQuery.sizeOf(context).width < kBreakpointSmall) {
  393. return 200.0;
  394. } else if (MediaQuery.sizeOf(context).width <
  395. kBreakpointMedium) {
  396. return 250.0;
  397. } else if (MediaQuery.sizeOf(context).width <
  398. kBreakpointLarge) {
  399. return 300.0;
  400. } else {
  401. return 350.0;
  402. }
  403. }(),
  404. decoration: BoxDecoration(),
  405. child: Column(
  406. mainAxisSize: MainAxisSize.min,
  407. mainAxisAlignment: MainAxisAlignment.start,
  408. crossAxisAlignment: CrossAxisAlignment.start,
  409. children: [
  410. Text(
  411. valueOrDefault<String>(
  412. widget!.titel,
  413. 'Titel onbekend',
  414. ),
  415. maxLines: 2,
  416. style:
  417. FlutterFlowTheme.of(context).titleMedium.override(
  418. font: GoogleFonts.roboto(
  419. fontWeight: FontWeight.w600,
  420. fontStyle: FlutterFlowTheme.of(context)
  421. .titleMedium
  422. .fontStyle,
  423. ),
  424. letterSpacing: 0.0,
  425. fontWeight: FontWeight.w600,
  426. fontStyle: FlutterFlowTheme.of(context)
  427. .titleMedium
  428. .fontStyle,
  429. ),
  430. ),
  431. Column(
  432. mainAxisSize: MainAxisSize.min,
  433. crossAxisAlignment: CrossAxisAlignment.start,
  434. children: [
  435. Text(
  436. valueOrDefault<String>(
  437. widget!.adres,
  438. 'Adres onbekend',
  439. ),
  440. style: FlutterFlowTheme.of(context)
  441. .bodyMedium
  442. .override(
  443. font: GoogleFonts.roboto(
  444. fontWeight: FlutterFlowTheme.of(context)
  445. .bodyMedium
  446. .fontWeight,
  447. fontStyle: FlutterFlowTheme.of(context)
  448. .bodyMedium
  449. .fontStyle,
  450. ),
  451. color: FlutterFlowTheme.of(context)
  452. .secondaryText,
  453. letterSpacing: 0.0,
  454. fontWeight: FlutterFlowTheme.of(context)
  455. .bodyMedium
  456. .fontWeight,
  457. fontStyle: FlutterFlowTheme.of(context)
  458. .bodyMedium
  459. .fontStyle,
  460. ),
  461. ),
  462. Text(
  463. valueOrDefault<String>(
  464. widget!.plaats,
  465. 'Plaats onbekend',
  466. ),
  467. style: FlutterFlowTheme.of(context)
  468. .bodyMedium
  469. .override(
  470. font: GoogleFonts.roboto(
  471. fontWeight: FlutterFlowTheme.of(context)
  472. .bodyMedium
  473. .fontWeight,
  474. fontStyle: FlutterFlowTheme.of(context)
  475. .bodyMedium
  476. .fontStyle,
  477. ),
  478. color: FlutterFlowTheme.of(context)
  479. .secondaryText,
  480. letterSpacing: 0.0,
  481. fontWeight: FlutterFlowTheme.of(context)
  482. .bodyMedium
  483. .fontWeight,
  484. fontStyle: FlutterFlowTheme.of(context)
  485. .bodyMedium
  486. .fontStyle,
  487. ),
  488. ),
  489. ].divide(SizedBox(height: 4.0)),
  490. ),
  491. ].divide(SizedBox(height: 8.0)),
  492. ),
  493. ),
  494. ),
  495. ].divide(SizedBox(width: 16.0)),
  496. ),
  497. ),
  498. ),
  499. );
  500. }
  501. }