import 'dart:async'; import 'dart:math'; import 'dart:typed_data'; import 'package:fikoyt_mesaici/apps/mesaici/servisler/fikoyt.mesaici.service.dart'; import 'package:fikoyt_mesaici/core/fikoyt.service.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart' show rootBundle; import 'package:get/get.dart'; import 'package:pdf/pdf.dart'; import 'package:pdf/widgets.dart' as pw; import 'package:printing/printing.dart'; const PdfColor green = PdfColor.fromInt(0xff9ce5d0); const PdfColor lightGreen = PdfColor.fromInt(0xffcdf1e7); const sep = 120.0; Future generateResume(PdfPageFormat format, CustomData data) async { final FikoYTMesaiciService servisMesaici = Get.put(FikoYTMesaiciService()); final profileImage = pw.MemoryImage( servisMesaici.profilResmi.value ?? (await rootBundle.load('assets/core/icons/logo.png')).buffer.asUint8List(), // (await rootBundle.load('assets/core/icons/logo.png')).buffer.asUint8List(), ); final doc = pw.Document(title: 'Özel Rapor', author: 'FikoYT Mesaici'); final pageTheme = await _myPageTheme(format); doc.addPage( pw.MultiPage( pageTheme: pageTheme, build: (pw.Context context) => [ pw.Partitions( children: [ pw.Partition( child: pw.Column( crossAxisAlignment: pw.CrossAxisAlignment.start, children: [ pw.Container( padding: const pw.EdgeInsets.only(left: 30, bottom: 5), child: pw.Column( crossAxisAlignment: pw.CrossAxisAlignment.start, children: [ pw.Text(servisMesaici.ayarlarModel?.value.hesapAyarlari.adSoyad ?? "İsim Girilmemiş", textScaleFactor: 2, style: pw.Theme.of(context).defaultTextStyle.copyWith(fontWeight: pw.FontWeight.bold)), pw.Padding(padding: const pw.EdgeInsets.only(top: 10)), pw.Text(servisMesaici.ayarlarModel?.value.hesapAyarlari.goreviniz ?? "Görev Tanımlanmamış", textScaleFactor: 1.2, style: pw.Theme.of(context).defaultTextStyle.copyWith(fontWeight: pw.FontWeight.bold, color: green)), pw.Padding(padding: const pw.EdgeInsets.only(top: 20)), pw.Row( crossAxisAlignment: pw.CrossAxisAlignment.start, mainAxisAlignment: pw.MainAxisAlignment.spaceBetween, children: [ // pw.Column( // crossAxisAlignment: pw.CrossAxisAlignment.start, // children: [ // pw.Text('568 Port Washington Road'), // pw.Text('Nordegg, AB T0M 2H0'), // pw.Text('Canada, ON'), // ], // ), _Category(title: data.baslik ?? "Verilmeyen Başlık"), pw.Spacer(), pw.Column( crossAxisAlignment: pw.CrossAxisAlignment.center, children: [ pw.Text(servisMesaici.ayarlarModel?.value.hesapAyarlari.sirket ?? "Şirket Belirtilmemiş", textAlign: pw.TextAlign.center, style: pw.TextStyle(fontWeight: pw.FontWeight.bold)), _UrlText('p.charlesbois@yahoo.com', 'mailto:p.charlesbois@yahoo.com'), _UrlText('wholeprices.ca', 'https://wholeprices.ca'), ], ), pw.Padding(padding: pw.EdgeInsets.zero) ], ), ], ), ), _Block(title: 'Tour bus driver', icon: const pw.IconData(0xe530)), _Block(title: 'Logging equipment operator', icon: const pw.IconData(0xe30d)), _Block(title: 'Foot doctor', icon: const pw.IconData(0xe3f3)), _Block(title: 'Unicorn trainer', icon: const pw.IconData(0xf0cf)), _Block(title: 'Chief chatter', icon: const pw.IconData(0xe0ca)), // pw.SizedBox(height: 20), // _Category(title: 'Education'), // _Block(title: 'Bachelor Of Commerce'), // _Block(title: 'Bachelor Interior Design'), ], ), ), // pw.Partition( // width: sep, // child: pw.Column( // children: [ // pw.Container( // height: pageTheme.pageFormat.availableHeight, // child: pw.Column( // crossAxisAlignment: pw.CrossAxisAlignment.center, // mainAxisAlignment: pw.MainAxisAlignment.spaceBetween, // children: [ // pw.ClipOval( // child: pw.Container( // width: 100, // height: 100, // color: lightGreen, // child: pw.Image( // profileImage, // width: 100, // height: 100, // fit: pw.BoxFit.cover, // ), // ), // ), // pw.Spacer(), // // pw.Column(children: [ // // _Percent(size: 60, value: .7, title: pw.Text('Word')), // // _Percent(size: 60, value: .4, title: pw.Text('Excel')), // // ]), // pw.BarcodeWidget( // data: 'Parnella Charlesbois', // width: 60, // height: 60, // barcode: pw.Barcode.qrCode(), // drawText: false, // ), // ], // ), // ), // ], // ), // ) ], ), ], ), ); return doc.save(); } Future _myPageTheme(PdfPageFormat format) async { final bgShape = await rootBundle.loadString('assets/mesaici/background/resume.svg'); final FikoYTMesaiciService servisMesaici = Get.put(FikoYTMesaiciService()); final profileImage = pw.MemoryImage( servisMesaici.profilResmi.value ?? (await rootBundle.load('assets/core/icons/logo.png')).buffer.asUint8List(), // (await rootBundle.load('assets/core/icons/logo.png')).buffer.asUint8List(), ); format = format.applyMargin(left: 1.0 * PdfPageFormat.cm, top: 1.0 * PdfPageFormat.cm, right: 1.0 * PdfPageFormat.cm, bottom: 1.0 * PdfPageFormat.cm); return pw.PageTheme( pageFormat: format, theme: pw.ThemeData.withFont( base: await PdfGoogleFonts.openSansRegular(), bold: await PdfGoogleFonts.openSansBold(), icons: await PdfGoogleFonts.materialIcons(), ), buildBackground: (pw.Context context) { return pw.FullPage( ignoreMargins: true, child: pw.Stack( children: [ pw.Positioned( right: 2.0 * PdfPageFormat.cm, top: 1.0 * PdfPageFormat.cm, child: pw.ClipOval( child: pw.Container( width: 100, height: 100, color: lightGreen, child: pw.Image( profileImage, width: 100, height: 100, fit: pw.BoxFit.cover, ), ), ), ), pw.Positioned( child: pw.SvgImage(svg: bgShape), left: 0, top: 0, ), pw.Positioned( child: pw.Transform.rotate(angle: pi, child: pw.SvgImage(svg: bgShape)), right: 0, bottom: 0, ), ], ), ); }, ); } class _Block extends pw.StatelessWidget { _Block({ required this.title, this.icon, }); final String title; final pw.IconData? icon; @override pw.Widget build(pw.Context context) { return pw.Column(crossAxisAlignment: pw.CrossAxisAlignment.start, children: [ pw.Row(crossAxisAlignment: pw.CrossAxisAlignment.start, children: [ pw.Container( width: 6, height: 6, margin: const pw.EdgeInsets.only(top: 5.5, left: 2, right: 5), decoration: const pw.BoxDecoration( color: green, shape: pw.BoxShape.circle, ), ), pw.Text(title, style: pw.Theme.of(context).defaultTextStyle.copyWith(fontWeight: pw.FontWeight.bold)), pw.Spacer(), if (icon != null) pw.Icon(icon!, color: lightGreen, size: 18), ]), pw.Container( decoration: const pw.BoxDecoration(border: pw.Border(left: pw.BorderSide(color: green, width: 2))), padding: const pw.EdgeInsets.only(left: 10, top: 5, bottom: 5), margin: const pw.EdgeInsets.only(left: 5), child: pw.Column(crossAxisAlignment: pw.CrossAxisAlignment.start, children: [ pw.Lorem(length: 20), ]), ), ]); } } class _Category extends pw.StatelessWidget { _Category({required this.title}); final String title; @override pw.Widget build(pw.Context context) { return pw.Container( decoration: const pw.BoxDecoration( color: lightGreen, borderRadius: pw.BorderRadius.all(pw.Radius.circular(6)), ), margin: const pw.EdgeInsets.only(bottom: 10, top: 20), padding: const pw.EdgeInsets.fromLTRB(10, 4, 10, 4), child: pw.Text( title, textScaleFactor: 1.5, style: const pw.TextStyle( color: PdfColors.redAccent700, ), ), ); } } class _Percent extends pw.StatelessWidget { _Percent({ required this.size, required this.value, required this.title, }); final double size; final double value; final pw.Widget title; static const fontSize = 1.2; PdfColor get color => green; static const backgroundColor = PdfColors.grey300; static const strokeWidth = 5.0; @override pw.Widget build(pw.Context context) { final widgets = [ pw.Container( width: size, height: size, child: pw.Stack( alignment: pw.Alignment.center, fit: pw.StackFit.expand, children: [ pw.Center( child: pw.Text( '${(value * 100).round().toInt()}%', textScaleFactor: fontSize, ), ), pw.CircularProgressIndicator( value: value, backgroundColor: backgroundColor, color: color, strokeWidth: strokeWidth, ), ], ), ) ]; widgets.add(title); return pw.Column(children: widgets); } } class _UrlText extends pw.StatelessWidget { _UrlText(this.text, this.url); final String text; final String url; @override pw.Widget build(pw.Context context) { return pw.UrlLink( destination: url, child: pw.Text(text, style: const pw.TextStyle( decoration: pw.TextDecoration.underline, color: PdfColors.blue, )), ); } } class CustomData { const CustomData({ this.name = '[your name]', this.testing = false, this.baslik = "Ağustos Ayı Çizelgesi", }); final String name; final bool testing; final String? baslik; }