product card

mail@pastecode.io avatar
unknown
dart
2 years ago
14 kB
1
Indexable
Never
import 'package:ease/ease.dart';
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';

class ProductCard extends StatefulWidget {
  final ImageProvider<Object> image;
  final String title;
  final String primarytActionLabel;
  final String price;
  final int rate;
  final VoidCallback? onSubAction;
  final VoidCallback? onPrimaryAction;
  final IconData icon;
  final List? files;
  final double closedHeight;
  final double openedHeight;
  const ProductCard(
      {Key? key,
      required this.image,
      required this.title,
      required this.primarytActionLabel,
      required this.price,
      required this.rate,
      this.onSubAction,
      this.onPrimaryAction,
      this.icon = Icons.favorite_border,
      this.files,
      this.closedHeight = 150,
      this.openedHeight = 300})
      : super(key: key);
  @override
  _ProductCardState createState() => _ProductCardState();
}

class _ProductCardState extends State<ProductCard>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation _animation;
  bool isOpened = false;

  void initState() {
    super.initState();
    _controller =
        AnimationController(duration: Duration(milliseconds: 375), vsync: this);
    _animation = Tween(begin: widget.closedHeight, end: widget.openedHeight)
        .animate(CurvedAnimation(
            parent: _controller,
            curve: Curves.easeOut,
            reverseCurve: Curves.easeOut));

    _controller.addListener(() {
      setState(() {});
    });
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      // color: Colors.grey[200],
      child: Center(
        child: InkWell(
          onTap: () {
            setState(() {
              isOpened = !isOpened;
              if (isOpened) {
                _controller.forward();
              } else {
                _controller.reverse();
              }
            });
          },
          child: Container(
            height: _animation.value,
            // width: 150.0,
            decoration: BoxDecoration(
              boxShadow: [
                BoxShadow(
                  color: Theme.of(context).shadowColor.withOpacity(.2),
                  blurRadius: 10.0,
                  spreadRadius: 2.0,
                  offset: Offset(0.0, -5.0),
                ),
              ],
              color: Theme.of(context).cardColor,
              borderRadius: BorderRadius.circular(20.0),
            ),

            child: Column(
              children: [
                Container(
                  margin: EdgeInsets.only(
                    top: 10.0,
                  ),
                  height: 130.0,
                  width: 130.0,
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.circular(15.0),
                    image: DecorationImage(
                      fit: BoxFit.fitWidth,
                      image: widget.image,
                    ),
                  ),
                ),
                SizedBox(
                  height: 8,
                ),
                widget.files != null
                    ? Flexible(
                        child: AnimatedOpacity(
                          opacity: _animation.value == widget.openedHeight
                              ? 1.0
                              : 0.0,
                          duration: Duration(milliseconds: 200),
                          child: Container(
                            child: Row(
                                children: List.generate(
                                    widget.files!.length,
                                    (index) => Card(
                                        color: index == 0
                                            ? Colors.red.shade200
                                            : index == 1
                                                ? Colors.orange.shade200
                                                : index == 2
                                                    ? Colors.green.shade200
                                                    : Colors.indigo.shade200,
                                        child: widget.files![index] == null
                                            ? Container()
                                            : widget.files![index]
                                                    .contains('pdf')
                                                ? InkWell(
                                                    onTap: () async {
                                                      if (!await launch(
                                                          widget.files![index]))
                                                        throw 'Could not launch $widget.files![index]';
                                                    },
                                                    child: Txt(
                                                      "  pdf  ",
                                                      color: Colors.white,
                                                    ))
                                                : widget.files![index]
                                                        .contains('pptx')
                                                    ? InkWell(
                                                        onTap: () async {
                                                          if (!await launch(
                                                              widget.files![
                                                                  index]))
                                                            throw 'Could not launch $widget.files![index]';
                                                        },
                                                        child: Txt("  pptx  ",
                                                            color:
                                                                Colors.white))
                                                    : widget.files![index]
                                                            .contains('  ppt  ')
                                                        ? InkWell(
                                                            onTap: () async {
                                                              if (!await launch(
                                                                  widget.files![
                                                                      index]))
                                                                throw 'Could not launch $widget.files![index]';
                                                            },
                                                            child: Txt(
                                                                "  ppt  ",
                                                                color: Colors
                                                                    .white))
                                                        : InkWell(
                                                            onTap: () async {
                                                              if (!await launch(
                                                                  widget.files![
                                                                      index]))
                                                                throw 'Could not launch $widget.files![index]';
                                                            },
                                                            child: Txt(
                                                                " Video ",
                                                                color: Colors
                                                                    .white))))),
                            decoration: BoxDecoration(
                              borderRadius: BorderRadius.circular(15.0),
                              color: Colors.white.withOpacity(.1),
                            ),
                          ),
                        ),
                      )
                    : Container(),
                Flexible(
                  flex: 3,
                  child: AnimatedOpacity(
                    opacity:
                        _animation.value == widget.openedHeight ? 1.0 : 0.0,
                    duration: Duration(milliseconds: 200),
                    child: Container(
                      child: Column(
                        mainAxisAlignment: MainAxisAlignment.spaceAround,
                        children: [
                          Flexible(
                            child: Txt(
                              widget.title,
                              weight: FontWeight.w600,
                            ),
                          ),
                          Flexible(
                            child: Container(
                              padding: EdgeInsets.symmetric(horizontal: 10.0),
                              child: Row(
                                mainAxisAlignment:
                                    MainAxisAlignment.spaceBetween,
                                crossAxisAlignment: CrossAxisAlignment.center,
                                children: [
                                  Column(
                                    crossAxisAlignment:
                                        CrossAxisAlignment.start,
                                    mainAxisAlignment: MainAxisAlignment.center,
                                    children: [
                                      Flexible(
                                        flex: 2,
                                        child: Text(
                                          widget.price,
                                        ),
                                      ),
                                      Flexible(
                                        child: Row(
                                          children: List.generate(
                                              widget.rate,
                                              (index) => starIcon(
                                                  Colors.yellow.shade700)),
                                        ),
                                      ),
                                    ],
                                  ),
                                  Flexible(
                                    child: Container(
                                      height: 30.0,
                                      width: 30.0,
                                      decoration: BoxDecoration(
                                        color: Colors.transparent,
                                        borderRadius:
                                            BorderRadius.circular(12.0),
                                      ),
                                      child: Material(
                                        color: Colors.grey[200],
                                        shape: RoundedRectangleBorder(
                                          borderRadius:
                                              BorderRadius.circular(12.0),
                                        ),
                                        child: InkWell(
                                          onTap: widget.onSubAction,
                                          child: Center(
                                            child: Icon(
                                              widget.icon,
                                              size: 15.0,
                                              color: Theme.of(context)
                                                  .primaryColor,
                                            ),
                                          ),
                                        ),
                                      ),
                                    ),
                                  ),
                                ],
                              ),
                            ),
                          ),
                          Flexible(
                            child: Container(
                              margin: EdgeInsets.only(bottom: 0.0),
                              width: 130.0,
                              height: 30.0,
                              decoration: BoxDecoration(
                                color: Colors.blue,
                                borderRadius: BorderRadius.circular(12.0),
                                boxShadow: [
                                  BoxShadow(
                                    color: Colors.blue.shade400,
                                    offset: Offset(0.0, 10.0),
                                    spreadRadius: -5.0,
                                    blurRadius: 10.0,
                                  ),
                                ],
                              ),
                              child: Material(
                                color: Colors.transparent,
                                shape: RoundedRectangleBorder(
                                  borderRadius: BorderRadius.circular(12.0),
                                ),
                                child: InkWell(
                                  onTap: widget.onPrimaryAction,
                                  child: Center(
                                    child: Text(
                                      widget.primarytActionLabel,
                                      style: TextStyle(color: Colors.white),
                                    ),
                                  ),
                                ),
                              ),
                            ),
                          ),
                        ],
                      ),
                    ),
                  ),
                )
              ],
            ),
          ),
        ),
      ),
    );
  }

  Icon starIcon(Color color) {
    return Icon(
      Icons.star,
      size: 10.0,
      color: color,
    );
  }
}