diff --git a/.gradle/8.0.2/checksums/checksums.lock b/.gradle/8.0.2/checksums/checksums.lock new file mode 100644 index 0000000..c90f709 Binary files /dev/null and b/.gradle/8.0.2/checksums/checksums.lock differ diff --git a/.gradle/8.0.2/fileChanges/last-build.bin b/.gradle/8.0.2/fileChanges/last-build.bin new file mode 100644 index 0000000..f76dd23 Binary files /dev/null and b/.gradle/8.0.2/fileChanges/last-build.bin differ diff --git a/.gradle/8.0.2/fileHashes/fileHashes.lock b/.gradle/8.0.2/fileHashes/fileHashes.lock new file mode 100644 index 0000000..4f02814 Binary files /dev/null and b/.gradle/8.0.2/fileHashes/fileHashes.lock differ diff --git a/.gradle/8.0.2/gc.properties b/.gradle/8.0.2/gc.properties new file mode 100644 index 0000000..e69de29 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..db5ca62 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 8afefca..509b64e 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,15 @@ OpSo is a Flutter app that provides comprehensive information about various open
+ +
+

License

+
+ +[![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) + +This project is licensed under the [MIT License](./LICENSE). + ## Contributing to OpSo Thank you for considering contributing to OpSo! We welcome contributions from the community to help improve the app and add new features. Below are some guidelines for contributing: diff --git a/assets/coding_ninja_swag.png b/assets/coding_ninja_swag.png new file mode 100644 index 0000000..55c39f3 Binary files /dev/null and b/assets/coding_ninja_swag.png differ diff --git a/assets/github_swag.png b/assets/github_swag.png new file mode 100644 index 0000000..ecdaeba Binary files /dev/null and b/assets/github_swag.png differ diff --git a/assets/open_summer_of_code.png b/assets/open_summer_of_code.png new file mode 100644 index 0000000..a5d2a31 Binary files /dev/null and b/assets/open_summer_of_code.png differ diff --git a/assets/participation_certificate.png b/assets/participation_certificate.png new file mode 100644 index 0000000..3c165b2 Binary files /dev/null and b/assets/participation_certificate.png differ diff --git a/assets/projects/osoc/osoc2021.json b/assets/projects/osoc/osoc2021.json new file mode 100644 index 0000000..5ec70ed --- /dev/null +++ b/assets/projects/osoc/osoc2021.json @@ -0,0 +1,93 @@ +[ + { + "name": "Reclaim your data", + "image_url": "https://osoc.be/editions/2021/projects/reclaim-your-data.svg", + "description": "Remember this nice picture your friend shared of you cliff jumping? So does your insurer - and he just raised your premium. WePod is creating a web application that allows you to get back control. Choose who gets to see which pictures and keep the ownership over your data.", + "project_url": "https://osoc.be/editions/2021/reclaim-your-data", + "year": 2021 + }, + { + "name": "Crowdy", + "image_url": "https://osoc.be/editions/2021/projects/crowdy.svg", + "description": "We will build a user-friendly web-app \"crowdedness meter\" to help students meet safely in Ghent hotspots. Our ultimate goal is to offer students the opportunity to reclaim the ownership of their reputation, by demonstrating that it is possible to have a social life while respecting government measures. For students, by students.", + "project_url": "https://osoc.be/editions/2021/crowdy", + "year": 2021 + }, + { + "name": "Open Talks", + "image_url": "https://osoc.be/editions/2021/projects/open-talks.svg", + "description": "Creating, organising and optimising the internal and external communication strategy for #osoc21. The goal is to document and share the experiences of all #osoc21 participants to the world and future students, coaches, sponsors and partners in a successful creative communication campaign on different media platforms.", + "project_url": "https://osoc.be/editions/2021/open-talks", + "year": 2021 + }, + { + "name": "Future of Work", + "image_url": "https://osoc.be/editions/2021/projects/future-of-work.svg", + "description": "Our goal is to create an application that analyzes the inflow and outflow of personnel and creates fancy, useful visualizations.", + "project_url": "https://osoc.be/editions/2021/future-of-work", + "year": 2021 + }, + { + "name": "Edubadges (Belgium)", + "image_url": "https://osoc.be/editions/2021/projects/edubadges-be.svg", + "description": "We will be creating a campaign to successfully bring Edubadges to the Belgian public in the future. The communication plan will inform the viewer about Edubadges and its advantages.", + "project_url": "https://osoc.be/editions/2021/edubadges-be", + "year": 2021 + }, + { + "name": "selection-tool", + "image_url": "https://osoc.be/editions/2021/projects/selection-tool.svg", + "description": "Creating a selection tool for recruiters giving them the opportunity to collaborate in real time while having an overview of all the candidates, resulting in diverse, innovative teams for all orgranisations. Giving orgranisations the opportunity to find the best candidates and match them to the preferred team.", + "project_url": "https://osoc.be/editions/2021/selection-tool", + "year": 2021 + }, + { + "name": "Arvesta's Digital Innovation Hackathon", + "image_url": "https://osoc.be/editions/2021/projects/arvesta-s-digital-innovation-hackathon.svg", + "description": "How to connect the different stakeholders of Arvesta, the largest full-service partner for Belgian farmers and market gardeners? Sharing their knowledge to become more aware, so they can improve their skills and attitudes.", + "project_url": "https://osoc.be/editions/2021/arvesta-s-digital-innovation-hackathon", + "year": 2021 + }, + { + "name": "Final Improved String pHarser (FISH)", + "image_url": "https://osoc.be/editions/2021/projects/fish.svg", + "description": "extract data from scientific references and store it in a usable format. We split strings, containing citations and references, into the correct author, year, journal and publication.", + "project_url": "https://osoc.be/editions/2021/fish", + "year": 2021 + }, + { + "name": "Nature moves", + "image_url": "https://osoc.be/editions/2021/projects/nature-moves.svg", + "description": "Our goal is to build a map visualisation and editing tool to enrich and integrate the Natuurpunt’s nature reserves data into the OSM database, making it both accessible, maintainable, and mobile-friendly.", + "project_url": "https://osoc.be/editions/2021/nature-moves", + "year": 2021 + }, + { + "name": "Safe Crossing", + "image_url": "https://osoc.be/editions/2021/projects/safe-crossing.svg", + "description": "This project is about determining which crosswalk a pedestrian is about to cross with a mobile phone and optionally hardware devices installed on the intersection. Pedestrians and specially blind people are the target audiance for this project.", + "project_url": "https://osoc.be/editions/2021/safe-crossing", + "year": 2021 + }, + { + "name": "RoadBase", + "image_url": "https://osoc.be/editions/2021/projects/roadbase.svg", + "description": "Crowd-sourcing information about road marks in linked open data structure to enable (local) governments, companies & citizens to use and reuse this data, build new applications and create new roads to safety.", + "project_url": "https://osoc.be/editions/2021/roadbase", + "year": 2021 + }, + { + "name": "Linked Data Event Streams", + "image_url": "https://osoc.be/editions/2021/projects/ldes.svg", + "description": "Our goal is to build an SDK to make it easier for Data Publisher/Developers to publish their datasets as Linked Data Event Streams (LDES) and showcase its potential by creating a use-case for public transport services", + "project_url": "https://osoc.be/editions/2021/ldes", + "year": 2021 + }, + { + "name": "BikeInfrastructure", + "image_url": "https://osoc.be/editions/2021/projects/bikeinfrastructure.svg", + "description": "We will build a user-friendly and visually attractive tool to visualize and promote the Open Street Maps data on cycling infrastructure in the province of East-Flanders.", + "project_url": "https://osoc.be/editions/2021/bikeinfrastructure", + "year": 2021 + } +] diff --git a/assets/projects/osoc/osoc2022.json b/assets/projects/osoc/osoc2022.json new file mode 100644 index 0000000..b65dd42 --- /dev/null +++ b/assets/projects/osoc/osoc2022.json @@ -0,0 +1,72 @@ +[ + { + "name": "Removing Obstacles with Open Data", + "image_url": "https://osoc.be/editions/2022/projects/removing-obstacles-with-open-data.svg", + "description": "We strive to make the world more accessible for people with a physical disability by creating a web application where public places and data about accessibility will be mapped, so that it will become available to consult, add and analyze.", + "project_url": "https://osoc.be/editions/2022/removing-obstacles-with-open-data", + "year": 2022 + }, + { + "name": "The Impact of Sharing Knowledge", + "image_url": "https://osoc.be/editions/2022/projects/the-impact-of-sharing-knowledge.svg", + "description": "Motivate and inspire researchers to keep sharing their research output and knowledge on knowledge portals such as FRIS and Biblio in a durable, qualitative, sustainable & enthusiastic way.", + "project_url": "https://osoc.be/editions/2022/the-impact-of-sharing-knowledge", + "year": 2022 + }, + { + "name": "We spice up your osoc", + "image_url": "https://osoc.be/editions/2022/projects/we-spice-up-your-osoc.svg", + "description": "We manage internal and external communications of #osoc22 and set up a new branding strategy for #osoc23. We promote this summer programme to future participants and partners.", + "project_url": "https://osoc.be/editions/2022/we-spice-up-your-osoc", + "year": 2022 + }, + { + "name": "Powerful Personal Data", + "image_url": "https://osoc.be/editions/2022/projects/powerful-personal-data.svg", + "description": "We're a team researching and coding to demonstrate how \"taking back control of your personal data\" can really empower everyone in their daily lives.", + "project_url": "https://osoc.be/editions/2022/powerful-personal-data", + "year": 2022 + }, + { + "name": "Paradar", + "image_url": "https://osoc.be/editions/2022/projects/paradar.svg", + "description": "Developing a proof of concept for a tracking app based on physical trackers and smartphones to allow NCCN to track useful resources (VIP, assets, ...) in their internal tools (crisis management, emergency planning, ...)", + "project_url": "https://osoc.be/editions/2022/paradar", + "year": 2022 + }, + { + "name": "VAC - Voice Assistant Confidentiality", + "image_url": "https://osoc.be/editions/2022/projects/vac-voice-assistant-confidentiality.svg", + "description": "VAC - Voice Assistant Confidentiality project aims to deliver offline voice assistant and research use cases with a focus on sexual harassment.", + "project_url": "https://osoc.be/editions/2022/vac-voice-assistant-confidentiality", + "year": 2022 + }, + { + "name": "LYNX - Local Linked Taxes", + "image_url": "https://osoc.be/editions/2022/projects/lynx-local-linked-taxes.svg", + "description": "Informing & involving citizens, organizations, companies and governments with Linked Open Data. With this project, we aim to increase the quality of data about municipal taxes and to open it up.", + "project_url": "https://osoc.be/editions/2022/lynx-local-linked-taxes", + "year": 2022 + }, + { + "name": "Pleasant Procedures", + "image_url": "https://osoc.be/editions/2022/projects/pleasant-procedures.svg", + "description": "We want to develop an easy-to-use web tool for government administrators, with which they can design data-gathering flows for citizens (procedures). For example, a flow for requesting a new identity card.", + "project_url": "https://osoc.be/editions/2022/pleasant-procedures", + "year": 2022 + }, + { + "name": "Inspector Widget", + "image_url": "https://osoc.be/editions/2022/projects/inspector-widget.svg", + "description": "We will make sure that fraud during sales periods won't happen anymore! Our aim is to help FOD Economie inspectors providing them an app that makes sure that prices advertised online are correct based on rules and regulations.", + "project_url": "https://osoc.be/editions/2022/inspector-widget", + "year": 2022 + }, + { + "name": "Sphere", + "image_url": "https://osoc.be/editions/2022/projects/sphere.svg", + "description": "We help first-time home-builders imagine and configure their dream house by providing 3D visualisations.", + "project_url": "https://osoc.be/editions/2022/sphere", + "year": 2022 + } +] diff --git a/assets/projects/sokde/sokde2022.json b/assets/projects/sokde/sokde2022.json new file mode 100644 index 0000000..4475f91 --- /dev/null +++ b/assets/projects/sokde/sokde2022.json @@ -0,0 +1,52 @@ +[ + { + "title": "Adding new Activity to GCompris", + "link": "https://community.kde.org/SoK/2022/StatusReport/Samarth_Raj", + "mentors": ["Emmanuel Charruau", "Harsh Kumar"], + "mentees": ["Samarth Raj"], + "year": 2022 + }, + { + "title": "Rust Wrapper of KConfig", + "link": "https://community.kde.org/SoK/2022/StatusReport/Ayush_Singh", + "mentors": ["Jos van den Oever"], + "mentees": ["Ayush Singh"], + "year": 2022 + }, + { + "title": "Adding Perspective Ellipse Assistant Tool in Krita", + "link": "https://community.kde.org/SoK/2022/StatusReport/Srirupa_Datta", + "mentors": ["Halla Rempt"], + "mentees": ["Srirupa Datta"], + "year": 2022 + }, + { + "title": "Improving UX for KDE Connect iOS Internal Error and Alerts", + "link": "https://community.kde.org/SoK/2022/StatusReport/Stefan_Kowalczyk", + "mentors": ["Lucas Wang", "Apollo Zhu"], + "mentees": ["Stefan Kowalczyk"], + "year": 2022 + }, + { + "title": "Packaging KDE Applications for Flathub", + "link": "https://community.kde.org/SoK/2022/StatusReport/Snehit_Sah", + "mentors": ["Timothée Ravier"], + "mentees": ["Snehit Sah"], + "year": 2022 + }, + { + "title": "Permission Management for Flatpak Apps in Discover", + "link": "https://community.kde.org/SoK/2022/StatusReport/Suhaas_Joshi", + "mentors": ["Timothée Ravier", "Aleix Pol"], + "mentees": ["Suhaas Joshi"], + "year": 2022 + }, + { + "title": "Preparing Standard Usage Scenarios for Energy Consumption Measurements", + "link": "https://community.kde.org/SoK/2022/StatusReport/Karanjot_Singh", + "mentors": ["Joseph P. De Veaugh-Geiss"], + "mentees": ["Karanjot Singh"], + "year": 2022 + } + ] + \ No newline at end of file diff --git a/assets/projects/sokde/sokde2023.json b/assets/projects/sokde/sokde2023.json new file mode 100644 index 0000000..5ab0ca4 --- /dev/null +++ b/assets/projects/sokde/sokde2023.json @@ -0,0 +1,79 @@ +[ + { + "title": "Preparation of KDE apps for Blue Angel eco-certification", + "link": "https://community.kde.org/SoK/Ideas/2023#Sustainability_1:_Preparation_of_KDE_apps_for_Blue_Angel_eco-certification", + "mentors": ["Joseph P. De Veaugh-Geiss"], + "mentees": ["Rudraksh Karpe"], + "year": 2023 + }, + { + "title": "Improve KDE Eco Test emulation tool", + "link": "https://community.kde.org/SoK/Ideas/2023#Sustainability_2:_Improve_KDE_Eco_Test_emulation_tool", + "mentors": ["Karanjot Singh", "Emmanuel Charruau", "Joseph P. De Veaugh-Geiss"], + "mentees": ["Mohammed Ibrahim"], + "year": 2023 + }, + { + "title": "Measurement of energy consumption with Selenium", + "link": "https://community.kde.org/SoK/Ideas/2023#Sustainability_3:_Measurement_of_energy_consumption_with_Selenium", + "mentors": ["Emmanuel Charruau", "Harald Sitter"], + "mentees": ["Nitin Tejuja"], + "year": 2023 + }, + { + "title": "Accessibility and UI testing of Tokodon", + "link": "https://community.kde.org/SoK/Ideas/2023#Accessibility_and_UI_testing_of_Tokodon", + "mentors": ["Carl Schwan"], + "mentees": ["Rishi Kumar"], + "year": 2023 + }, + { + "title": "Improving the accessibility of KDE’s websites", + "link": "https://community.kde.org/SoK/Ideas/2023#Improving_the_accessibility_of_KDE.E2.80.99s_websites", + "mentors": ["Paul Brown", "Aniqa Khokhar"], + "mentees": ["Victoria Chen"], + "year": 2023 + }, + { + "title": "Plasma accessibility widget", + "link": "https://community.kde.org/SoK/Ideas/2023#Plasma_accessibility_widget", + "mentors": ["Fushan Wen"], + "mentees": ["Brent Mackey"], + "year": 2023 + }, + { + "title": "Automate Flatpak checks in GitLab Invent CI", + "link": "https://community.kde.org/SoK/Ideas/2023#Automate_Flatpak_checks_in_GitLab_Invent_CI", + "mentors": ["Timothée Ravier", "Aleix Pol"], + "mentees": ["Neelaksh Singh"], + "year": 2023 + }, + { + "title": "Spectacle: Improving the annotation tools", + "link": "https://community.kde.org/SoK/Ideas/2023#Spectacle:_Improving_the_annotation_tools", + "mentors": ["Bharadwaj Raju"], + "mentees": ["Brannon Aw"], + "year": 2023 + }, + { + "title": "Plasma: Better holiday support in the digital clock widget", + "link": "https://community.kde.org/SoK/Ideas/2023#Plasma:_Better_holiday_support_in_the_digital_clock_widget", + "mentors": ["Fushan Wen"], + "mentees": ["Ruoqing He"], + "year": 2023 + }, + { + "title": "Improving Audiotube", + "link": "https://community.kde.org/SoK/Ideas/2023#Improving_Audiotube", + "mentors": ["Carl Schwan", "Devin Lin", "Jonah Brüchert"], + "mentees": ["Théophile Gilgien"], + "year": 2023 + }, + { + "title": "New epub reader, Arianna", + "link": "https://community.kde.org/SoK/Ideas/2023#New_epub_reader.2C_Arianna", + "mentors": ["Carl Schwan"], + "mentees": ["Arpit Jain"], + "year": 2023 + } +] diff --git a/assets/projects/sokde/sokde2024.json b/assets/projects/sokde/sokde2024.json new file mode 100644 index 0000000..b16e92d --- /dev/null +++ b/assets/projects/sokde/sokde2024.json @@ -0,0 +1,100 @@ +[ + { + "title": "Adding multi-format rendering to Kdenlive", + "link": "https://invent.kde.org/teams/mentor-programs/2024/-/issues/5", + "mentors": ["Julius Künzel", "Jean-Baptiste Mardelle"], + "mentees": ["Ajay Chauhan"], + "year": 2024 + }, + { + "title": "Enabling editing of keyframe curves and advanced keyframe types in Kdenlive", + "link": "https://invent.kde.org/teams/mentor-programs/2024/-/issues/4", + "mentors": ["Julius Künzel", "Jean-Baptiste Mardelle"], + "mentees": ["Iceneko"], + "year": 2024 + }, + { + "title": "Improving KdeEcoTest tool using kwin scripting API and uinput", + "link": "https://invent.kde.org/teams/mentor-programs/2024/-/issues/13", + "mentors": ["Karanjot Singh", "Emmanuel Charruau"], + "mentees": ["Athul Raj Kollareth"], + "year": 2024 + }, + { + "title": "Adding support for Windows in KdeEcoTest", + "link": "https://invent.kde.org/teams/mentor-programs/2024/-/issues/17", + "mentors": ["Karanjot Singh", "Emmanuel Charruau"], + "mentees": ["Amartya Chakraborty"], + "year": 2024 + }, + { + "title": "Testing and development of KEcoLab", + "link": "https://invent.kde.org/teams/mentor-programs/2024/-/issues/19", + "mentors": ["Nitin Tejuja"], + "mentees": ["Sarthak Negi", "Aakarsh MJ"], + "year": 2024 + }, + { + "title": "Selenium automation of energy measurements / accessibility tests for KDE applications", + "link": "https://invent.kde.org/teams/mentor-programs/2024/-/issues/14", + "mentors": ["Rishi Kumar", "Joseph P. De Veaugh-Geiss"], + "mentees": ["Pradyot Ranjan"], + "year": 2024 + }, + { + "title": "Extending embedded documentation for supported Computer Algebra Systems Project", + "link": "https://invent.kde.org/teams/mentor-programs/2024/-/issues/6", + "mentors": ["Alexander Semke"], + "mentees": ["Dhairya Majmudar", "Saksham Gupta"], + "year": 2024 + }, + { + "title": "Enhancing Cantor's and LabPlot's documentation by adding QtHelp Conversion and User Accessibility", + "link": "https://invent.kde.org/teams/mentor-programs/2024/-/issues/11", + "mentors": ["Alexander Semke"], + "mentees": ["Mahfuza Humayra Mohona"], + "year": 2024 + }, + { + "title": "Integrating KTextEditor into Cantor", + "link": "https://invent.kde.org/teams/mentor-programs/2024/-/issues/23", + "mentors": ["Alexander Semke"], + "mentees": ["Anshul Dalal"], + "year": 2024 + }, + { + "title": "Enhancing Cantor with package management capabilities", + "link": "https://invent.kde.org/teams/mentor-programs/2024/-/issues/25", + "mentors": ["Alexander Semke"], + "mentees": ["Krish Jain"], + "year": 2024 + }, + { + "title": "Downloading/importing of data sets from kaggle.com", + "link": "https://invent.kde.org/teams/mentor-programs/2024/-/issues/9", + "mentors": ["Alexander Semke"], + "mentees": ["Israel Galadima"], + "year": 2024 + }, + { + "title": "Integrating TSDB support to LabPlot", + "link": "https://invent.kde.org/teams/mentor-programs/2024/-/issues/29", + "mentors": ["Alexander Semke"], + "mentees": ["Mihir Kumar Singh"], + "year": 2024 + }, + { + "title": "MCAP Support for LabPlot", + "link": "https://invent.kde.org/teams/mentor-programs/2024/-/issues/30", + "mentors": ["Alexander Semke"], + "mentees": ["Raphael Wirth"], + "year": 2024 + }, + { + "title": "Moving brightness control to KWin and adding per-screen brightness control", + "link": "https://invent.kde.org/teams/mentor-programs/2024/-/issues/20", + "mentors": ["Xaver Hugl"], + "mentees": ["Anurag Thakur"], + "year": 2024 + } +] diff --git a/assets/sokde.png b/assets/sokde.png new file mode 100644 index 0000000..2f95d01 Binary files /dev/null and b/assets/sokde.png differ diff --git a/assets/xyz_domain.png b/assets/xyz_domain.png new file mode 100644 index 0000000..24a67e9 Binary files /dev/null and b/assets/xyz_domain.png differ diff --git a/lib/home_page.dart b/lib/home_page.dart index 57fe0b7..62c226b 100644 --- a/lib/home_page.dart +++ b/lib/home_page.dart @@ -11,7 +11,9 @@ import 'package:opso/programs%20screen/google_season_of_docs_screen.dart'; import 'package:opso/programs%20screen/google_summer_of_code_screen.dart'; import 'package:opso/programs%20screen/linux_foundation.dart'; import 'package:opso/programs%20screen/major_league_hacking_fellowship.dart'; +import 'package:opso/programs%20screen/open_summer_of_code.dart'; import 'package:opso/programs%20screen/outreachy.dart'; +import 'package:opso/programs%20screen/season_of_kde.dart'; import 'package:opso/programs%20screen/summer_of_bitcoin.dart'; import 'package:opso/programs%20screen/social_winter_of_code.dart'; import 'package:opso/services/notificationService.dart'; @@ -38,6 +40,7 @@ class _HomePageState extends State { void initState() { showNotification(); super.initState(); + _getInitialThemeMode(); } @@ -54,6 +57,7 @@ class _HomePageState extends State { _initialLabelIndex = 0; } }); + } @@ -109,6 +113,14 @@ class _HomePageState extends State { title: 'Social Winter of Code', imageAssetPath: 'assets/swoc.png', ), + Program( + title: 'Season of KDE', + imageAssetPath: 'assets/sokde.png', + ), + Program( + title: 'Open Summer of Code', + imageAssetPath: 'assets/open_summer_of_code.png', + ), ]; @@ -186,7 +198,10 @@ class _HomePageState extends State { child: Row( mainAxisAlignment: MainAxisAlignment.start, children: [ - Icon(FontAwesomeIcons.bars), + IconButton( + icon: Icon(Icons.close), + onPressed: () => Navigator.pop(context), + ), SizedBox( width: ScreenUtil().setWidth(100), ), @@ -215,20 +230,15 @@ class _HomePageState extends State { onTap: () {}, child: ListTile( leading: Icon( - _initialLabelIndex == 0 + AdaptiveTheme.of(context).mode.isDark ? FontAwesomeIcons.solidSun : FontAwesomeIcons.solidMoon, ), title: const Text('Switch Theme'), onTap: () { setState(() { - if (_initialLabelIndex == 0) { - _initialLabelIndex = 1; - AdaptiveTheme.of(context).setDark(); - } else { - _initialLabelIndex = 0; - AdaptiveTheme.of(context).setLight(); - } + AdaptiveTheme.of(context) + .toggleThemeMode(useSystem: false); }); }, ), @@ -379,6 +389,15 @@ class _HomePageState extends State { ); break; + case 'Season of KDE': + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const SeasonOfKDE(), + ), + ); + break; + case 'Outreachy': Navigator.push(context, @@ -388,12 +407,12 @@ class _HomePageState extends State { case 'Summer of Bitcoin': Navigator.pushNamed(context, "/summer_of_bitcoin"); + case 'Open Summer of Code': - case 'Summer of Bitcoin': Navigator.push( context, MaterialPageRoute( - builder: (context) => const SummerOfBitcoin(), + builder: (context) => const OpenSummerOfCode(), ), ); @@ -401,6 +420,7 @@ class _HomePageState extends State { case 'Linux Foundation': Navigator.push(context, MaterialPageRoute(builder: (context) => const LinuxFoundation())); + default: break; } @@ -503,6 +523,14 @@ class ProgramSearchDelegate extends SearchDelegate { title: 'Social Winter of Code', imageAssetPath: 'assets/swoc.png', ), + Program( + title: 'Season of KDE', + imageAssetPath: 'assets/sokde.png', + ), + Program( + title: 'Open Summer of Code', + imageAssetPath: 'assets/open_summer_of_code.png', + ), ]; @@ -610,6 +638,15 @@ class ProgramSearchDelegate extends SearchDelegate { ); break; + case 'Season of KDE': + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const SeasonOfKDE(), + ), + ); + break; + case 'Linux Foundation': Navigator.push(context, diff --git a/lib/main.dart b/lib/main.dart index 87e2cd7..ee6ebe4 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -6,7 +6,9 @@ import 'package:opso/programs%20screen/google_season_of_docs_screen.dart'; import 'package:opso/programs%20screen/google_summer_of_code_screen.dart'; import 'package:opso/programs%20screen/linux_foundation.dart'; import 'package:opso/programs%20screen/major_league_hacking_fellowship.dart'; +import 'package:opso/programs%20screen/open_summer_of_code.dart'; import 'package:opso/programs%20screen/outreachy.dart'; +import 'package:opso/programs%20screen/season_of_kde.dart'; import 'package:opso/programs%20screen/summer_of_bitcoin.dart'; import 'package:opso/programs%20screen/social_winter_of_code.dart'; import 'package:opso/services/notificationService.dart'; @@ -16,12 +18,14 @@ import 'splash_screen.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); + final savedThemeMode = await AdaptiveTheme.getThemeMode(); await NotificationService.initialNotification(); - runApp(const OpSoApp()); + runApp(OpSoApp(savedThemeMode: savedThemeMode)); } class OpSoApp extends StatelessWidget { - const OpSoApp({super.key}); + final AdaptiveThemeMode? savedThemeMode; + const OpSoApp({super.key, this.savedThemeMode}); @override Widget build(BuildContext context) { @@ -33,18 +37,20 @@ class OpSoApp extends StatelessWidget { return AdaptiveTheme( light: ThemeData.light(), dark: ThemeData.dark(), - initial: AdaptiveThemeMode.system, + initial: savedThemeMode ?? AdaptiveThemeMode.light, builder: (theme, darkTheme) => MaterialApp( initialRoute: '/splash_screen', routes: { "/progarm_page": (context) => const HomePage(), "/girl_script_summer_of_code": (context) => const GSSOCScreen(), "/social_winter_of_code": (context) => const SWOCScreen(), + "/season_of_sokde":(context) => const SeasonOfKDE(), "/google_summer_of_code": (context) => GoogleSummerOfCodeScreen(), "/google_season_of_docs": (context) => GoogleSeasonOfDocsScreen(), "/summer_of_bitcoin": (context) => const SummerOfBitcoin(), + "/open_summer_of_code": (context) => const OpenSummerOfCode(), "/outreachy": (context) => const OutReachy(), "/major_league_hacking_fellowship": (context) => const MajorLeagueHackingFellowship(), diff --git a/lib/modals/osoc_modal.dart b/lib/modals/osoc_modal.dart new file mode 100644 index 0000000..03bca90 --- /dev/null +++ b/lib/modals/osoc_modal.dart @@ -0,0 +1,83 @@ +// ignore_for_file: public_member_api_docs, sort_constructors_first, non_constant_identifier_names +import 'dart:convert'; + +class OsocModal { + String name = ""; + String image_url = ""; + String description = ""; + String project_url = ""; + int year = 0; + OsocModal({ + required this.name, + required this.image_url, + required this.description, + required this.project_url, + required this.year, + }); + + OsocModal copyWith({ + String? name, + String? image_url, + String? description, + String? project_url, + int? year, + }) { + return OsocModal( + name: name ?? this.name, + image_url: image_url ?? this.image_url, + description: description ?? this.description, + project_url: project_url ?? this.project_url, + year: year ?? this.year, + ); + } + + Map toMap() { + return { + 'name': name, + 'image_url': image_url, + 'description': description, + 'project_url': project_url, + 'year': year, + }; + } + + factory OsocModal.fromMap(Map map) { + return OsocModal( + name: map['name'] as String, + image_url: map['image_url'] as String, + description: map['description'] as String, + project_url: map['project_url'] as String, + year: map['year'] as int, + ); + } + + String toJson() => json.encode(toMap()); + + factory OsocModal.fromJson(String source) => + OsocModal.fromMap(json.decode(source) as Map); + + @override + String toString() { + return 'OsocModal(name: $name, image_url: $image_url, description: $description, project_url: $project_url, year: $year)'; + } + + @override + bool operator ==(covariant OsocModal other) { + if (identical(this, other)) return true; + + return other.name == name && + other.image_url == image_url && + other.description == description && + other.project_url == project_url && + other.year == year; + } + + @override + int get hashCode { + return name.hashCode ^ + image_url.hashCode ^ + description.hashCode ^ + project_url.hashCode ^ + year.hashCode; + } +} diff --git a/lib/modals/sokde_project_modal.dart b/lib/modals/sokde_project_modal.dart new file mode 100644 index 0000000..fbb92f0 --- /dev/null +++ b/lib/modals/sokde_project_modal.dart @@ -0,0 +1,54 @@ +class SokdeProjectModal { + String name; + String wiki; + List mentees; + List mentors; + String year; + + SokdeProjectModal({ + required this.name, + required this.wiki, + required this.mentees, + required this.mentors, + required this.year, + }); + + factory SokdeProjectModal.fromJson(Map json) { + List mentorsList = []; + if (json['mentors'] is List) { + mentorsList = List.from(json['mentors']); + } else if (json['mentors'] is String) { + mentorsList = [json['mentors']]; + } + + List menteesList = []; + if (json['mentees'] is List) { + menteesList = List.from(json['mentees']); + } else if (json['mentees'] is String) { + menteesList = [json['mentees']]; + } + + return SokdeProjectModal( + name: json['title'], + wiki: json['link'], + mentors: mentorsList, + mentees: menteesList, + year: json['year'].toString(), // Ensure year is converted to string if necessary + ); + } + + Map toJson() { + return { + 'title': name, + 'link': wiki, + 'mentors': mentors, + 'mentees': mentees, + 'year': year, + }; + } + + @override + String toString() { + return 'SokdeProjectModal(name: $name, wiki: $wiki, mentees: $mentees, mentors: $mentors, year: $year)'; + } +} diff --git a/lib/opso_timeline.dart b/lib/opso_timeline.dart index 7591bba..c66b5de 100644 --- a/lib/opso_timeline.dart +++ b/lib/opso_timeline.dart @@ -9,6 +9,12 @@ class OpsoTimeLineScreen extends StatelessWidget { @override Widget build(BuildContext context) { final List> events = [ + { + 'description': + "Season of KDE-Mentorship\nApplication Period - 15/12/2023 to 08/01/2024", + 'startDate': DateTime.utc(2024, 12, 15), + 'endDate': DateTime.utc(2024, 1, 8), + }, { 'description': "Outreachy(May Internships)\nApplication Period - 15/01/2024 to 31/01/2024", @@ -45,6 +51,12 @@ class OpsoTimeLineScreen extends StatelessWidget { 'startDate': DateTime.utc(2024, 3, 31), 'endDate': DateTime.utc(2024, 4, 15), }, + { + 'description': + "Open Summer of Code\nApplication Period - 1/04/2024 to 29/04/2024", + 'startDate': DateTime.utc(2024, 4, 1), + 'endDate': DateTime.utc(2024, 4, 29), + }, { 'description': "MLH Fellowship(Fall Term)\nApplication Period - 15/04/2024 to 31/05/2024", diff --git a/lib/programs screen/girl_script.dart b/lib/programs screen/girl_script.dart index 54c03a5..ec8f473 100644 --- a/lib/programs screen/girl_script.dart +++ b/lib/programs screen/girl_script.dart @@ -5,6 +5,7 @@ import 'package:multi_select_flutter/dialog/multi_select_dialog_field.dart'; import 'package:multi_select_flutter/util/multi_select_item.dart'; import 'package:opso/modals/book_mark_model.dart'; import 'package:opso/modals/gssoc_project_modal.dart'; +import 'package:opso/programs_info_pages/gssoc_info.dart'; import 'package:opso/widgets/gssoc_project_widget.dart'; import 'package:opso/widgets/year_button.dart'; import '../widgets/SearchandFilterWidget.dart'; @@ -209,7 +210,16 @@ class _GSSOCScreenState extends State { HandleBookmark.deleteBookmark(currentProject); } }, - ) + ), + IconButton( + icon: const Icon(Icons.info_outline), + onPressed: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => const GSSOCInfo()), + ); + }, + ), ]), body: FutureBuilder( future: getProjectFunction, diff --git a/lib/programs screen/google_season_of_docs_screen.dart b/lib/programs screen/google_season_of_docs_screen.dart index 8c66f0a..11ecced 100644 --- a/lib/programs screen/google_season_of_docs_screen.dart +++ b/lib/programs screen/google_season_of_docs_screen.dart @@ -8,6 +8,7 @@ import 'package:opso/modals/gsod/gsod_modal_old.dart'; import 'package:opso/widgets/gsod/gsod_project_widget_new.dart'; import 'package:opso/widgets/gsod/gsod_project_widget_old.dart'; import 'package:opso/widgets/year_button.dart'; +import 'package:opso/programs_info_pages/gsod_info.dart'; @@ -290,7 +291,16 @@ class _GoogleSeasonOfDocsScreenState extends State { HandleBookmark.deleteBookmark(currentProgram); } }, - ) + ), + IconButton( + icon: const Icon(Icons.info_outline), + onPressed: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => const GSODInfo()), + ); + }, + ), ]), body: FutureBuilder( future: getProjectFunction, diff --git a/lib/programs screen/google_summer_of_code_screen.dart b/lib/programs screen/google_summer_of_code_screen.dart index 98a5e1e..39ae9cc 100644 --- a/lib/programs screen/google_summer_of_code_screen.dart +++ b/lib/programs screen/google_summer_of_code_screen.dart @@ -1,5 +1,6 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:opso/programs_info_pages/gsoc_info.dart'; import 'package:opso/widgets/gsoc/GsocProjectWidget.dart'; import 'package:url_launcher/url_launcher.dart'; import 'package:multi_select_flutter/multi_select_flutter.dart'; @@ -202,7 +203,15 @@ class _GoogleSummerOfCodeScreenState extends State { onRefresh: _refresh, child: Scaffold( appBar: AppBar( - title: Text('Google Summer of Code'), + title: const Text('Google Summer of Code'), + actions: [IconButton( + icon: const Icon(Icons.info_outline), + onPressed: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => const GSOCInfo()), ); + }, + ),], ), body: FutureBuilder( future: _dataFetchFuture, diff --git a/lib/programs screen/linux_foundation.dart b/lib/programs screen/linux_foundation.dart index 4734921..a4b049c 100644 --- a/lib/programs screen/linux_foundation.dart +++ b/lib/programs screen/linux_foundation.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:opso/modals/book_mark_model.dart'; import 'package:opso/modals/linux_foundation_modal.dart'; +import 'package:opso/programs_info_pages/linux_info.dart'; import 'package:opso/widgets/linux_foundation_widget.dart'; class LinuxFoundation extends StatefulWidget { @@ -99,7 +100,16 @@ class _LinuxFoundationState extends State { HandleBookmark.deleteBookmark(currentProject); } }, - ) + ), + IconButton( + icon: const Icon(Icons.info_outline), + onPressed: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => const LINUXInfo()), + ); + }, + ), ]), body: FutureBuilder( future: getProjectListFunction, diff --git a/lib/programs screen/major_league_hacking_fellowship.dart b/lib/programs screen/major_league_hacking_fellowship.dart index ccf3175..eb86df8 100644 --- a/lib/programs screen/major_league_hacking_fellowship.dart +++ b/lib/programs screen/major_league_hacking_fellowship.dart @@ -1,33 +1,28 @@ import 'package:flutter/material.dart'; import 'package:opso/modals/book_mark_model.dart'; - - - +import 'package:timeline_tile/timeline_tile.dart'; +import 'package:url_launcher/url_launcher.dart'; class MajorLeagueHackingFellowship extends StatefulWidget { const MajorLeagueHackingFellowship({super.key}); - @override - State createState() => _MajorLeagueHackingFellowshipState(); + State createState() => + _MajorLeagueHackingFellowshipState(); } - -class _MajorLeagueHackingFellowshipState extends State { +class _MajorLeagueHackingFellowshipState + extends State { bool isBookmarked = true; String currectPage = "/major_league_hacking_fellowship"; String currentProject = "MajorLeagueHackingFellowship"; - @override void initState() { super.initState(); _checkBookmarkStatus(); } - - - Future _checkBookmarkStatus() async { bool bookmarkStatus = await HandleBookmark.isBookmarked(currentProject); setState(() { @@ -35,57 +30,347 @@ class _MajorLeagueHackingFellowshipState extends State _refresh() async { setState(() { //implement refresh logic here when ready + // Currently not fetching anything }); } - @override Widget build(BuildContext context) { + // Size constants + double screenWidth = MediaQuery.of(context).size.width; + double gap = screenWidth * 0.05; + double pad = screenWidth * 0.04; + double titleSize = screenWidth * 0.05; + double contentSize = screenWidth * 0.04; return RefreshIndicator( - onRefresh: _refresh, - child: Scaffold( + onRefresh: _refresh, + child: Scaffold( + appBar: AppBar(title: const Text('MLH Fellowship'), actions: [ + IconButton( + icon: (isBookmarked) + ? const Icon(Icons.bookmark_add_rounded) + : const Icon(Icons.bookmark_add_outlined), + onPressed: () { + setState(() { + isBookmarked = !isBookmarked; + }); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + isBookmarked ? 'Bookmark added' : 'Bookmark removed'), + duration: const Duration( + seconds: 2), // Adjust the duration as needed + ), + ); + if (isBookmarked) { + print("Adding"); + HandleBookmark.addBookmark(currentProject, currectPage); + } else { + print("Deleting"); + HandleBookmark.deleteBookmark(currentProject); + } + }, + ) + ]), + body: SingleChildScrollView( + padding: EdgeInsets.all(pad), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.symmetric(vertical: pad), + child: Text( + 'Learn Software Engineering through Open Source Projects', + style: TextStyle( + fontSize: titleSize, fontWeight: FontWeight.bold), + ), + ), + Padding( + padding: EdgeInsets.symmetric(vertical: pad), + child: Text( + 'A fully remote, 12-week internship alternative where participants earn a stipend ' + 'and learn to collaborate on real open source projects with peers and engineers from top companies.', + style: TextStyle( + fontSize: contentSize, + ), + ), + ), + Row( + children: [ + ElevatedButton( + style: ElevatedButton.styleFrom( + backgroundColor: Colors.orange, + foregroundColor: Colors.black, + ), + onPressed: () async { + await _launchUrl("https://fellowship.mlh.io/apply"); + }, + child: const Text("Apply Now")), + SizedBox(width: gap), + ElevatedButton( + onPressed: () async { + await _launchUrl( + "https://fellowship.mlh.io/programs/open-source"); + }, + child: const Text("Learn More")), + ], + ), + SizedBox(height: gap), + Padding( + padding: EdgeInsets.symmetric(vertical: pad), + child: Text( + 'Explore Fellowship Tracks', + style: TextStyle( + fontSize: titleSize, fontWeight: FontWeight.bold), + ), + ), + _buildTrackTile('Software Engineering', + 'For aspiring Software Engineers who want to experience what it\'s like to collaborate on real-world projects from our partners.', + () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const TrackDetailsScreen( + title: + 'What exactly is the Software Engineering Fellowship?', + description: + "Software Engineering is one of the most in-demand skills that tech companies are hiring for. As an MLH Fellow on the Software Engineering Track, you'll be matched to a real project from one of our partners. You'll experience what it's like to work on a real software engineering team first-hand, working on either open- or closed-source projects that tech companies depend on every day. ", + url: + "https://fellowship.mlh.io/programs/software-engineering", + ))); + }), + _buildTrackTile('Site Reliability Engineering', + 'For aspiring SREs who want to learn the skills required to keep systems running at scale.', + () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const TrackDetailsScreen( + title: + "What exactly is the Site Reliability Engineering Track?", + description: + "Site Reliability Engineering, also known as DevOps, is one of the most in-demand skills that tech companies are hiring for. It's a hybrid between software & systems engineering that works across product & infrastructure to make sure services are reliable & scalable.\nIn the Site Reliability Engineering Track of the MLH Fellowship, you'll learn the skills needed to keep products running. You'll write code and debug hard problems. By the end of the program, you will gain valuable technical skills and the experience needed for a career in Site Reliability Engineering.\nProgram participants will gain practical skills thanks to educational content from Linux Foundation Training & Certification's LFS201 – Essentials of System Administration training course, which covers how to administer, configure and upgrade Linux systems, along with the tools and concepts necessary to efficiently build and manage a production Linux infrastructure.", + url: + "https://fellowship.mlh.io/programs/site-reliability-engineering", + ))); + }), + _buildTrackTile('Web3 Engineering', + 'For hackers who want to dive deep into blockchain technology.', + () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const TrackDetailsScreen( + title: 'Web3 Track', + description: + "Web3 is the name given to internet services that are built using decentralized blockchains — the distributed ledger systems used by cryptocurrencies like Bitcoin and Ether. This underlying technology has broad applications, though, and Web3 has grown to encompass gaming, social platforms, crowdfunding, CRMs and more.\nIn the Web3 track of the MLH Fellowship, you'll learn the skills needed to build on this quickly evolving part of the web and contribute to cutting-edge Web3 applications. Through expert mentorship, you’ll learn how to code on blockchains like Solana, collaborate on a team, and debug hard problems. By the end of the program, you will gain valuable technical skills and the experience needed for a career in Web3 and beyond.", + url: + "https://fellowship.mlh.io/programs/web3-engineering", + ))); + }), + SizedBox(height: gap), + Padding( + padding: EdgeInsets.symmetric(vertical: pad), + child: Text( + "Sample Schedule", + style: TextStyle( + fontSize: titleSize, fontWeight: FontWeight.bold), + ), + ), + Padding( + padding: EdgeInsets.symmetric(vertical: pad), + child: Text( + "Here's what a typical day in the fellowship might look like. The program runs Monday - Friday in most major timezones.", + style: TextStyle( + fontSize: contentSize, + ), + ), + ), + SizedBox(height: gap), + _buildTimeline(), + SizedBox(height: gap), + Center( + child: ElevatedButton( + onPressed: () { + _launchUrl('https://hackp.ac/fellowship-faq'); + }, + child: const Text('Read the FAQ'), + ), + ), + ], + ), + ), + )); + } + Widget _buildTrackTile(String title, String description, VoidCallback onTap) { + return InkWell( + onTap: onTap, + child: Card( + surfaceTintColor: Colors.orange, + elevation: 4.0, + margin: const EdgeInsets.symmetric(vertical: 10.0), + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(title, + style: const TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: Colors.orange)), + const SizedBox(height: 8), + Text(description), + ], + ), + ), + ), + ); + } - appBar: AppBar( - title: const Text('OpSo'), - actions: [ - IconButton( - icon: (isBookmarked) - ? const Icon(Icons.bookmark_add_rounded) - : const Icon(Icons.bookmark_add_outlined), - onPressed: () { - setState(() { - isBookmarked = !isBookmarked; - }); - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text(isBookmarked ? 'Bookmark added' : 'Bookmark removed'), - duration: const Duration(seconds: 2), // Adjust the duration as needed - ), - ); - if(isBookmarked){ - print("Adding"); - HandleBookmark.addBookmark(currentProject, currectPage); - } - else{ - print("Deleting"); - HandleBookmark.deleteBookmark(currentProject); - } - }, - ) - ] + Widget _buildTimeline() { + return Column( + children: [ + _buildTimelineItem( + time: '10:00 AM', + title: 'Daily Standup', + description: + 'Start your day with your Pod\'s daily standup where you\'ll share what you\'re working on and eliminate blockers.', + ), + _buildTimelineItem( + time: '11:00 AM', + title: 'Pair Programming', + description: + 'Jump into a pair programming session with another fellow to put the finishing touches on a pull request you\'re working on together.', ), + _buildTimelineItem( + time: '12:00 PM', + title: 'Speaker Series', + description: + 'Attend one of the regular speaker sessions where you\'ll learn from engineers, founders, and talent experts.', + ), + _buildTimelineItem( + time: '02:00 PM', + title: 'Practical Curriculum', + description: + 'Go through the latest module on the LMS where you\'re learning practical skills you can apply right away.', + ), + _buildTimelineItem( + time: '05:00 PM', + title: 'Code Review', + description: + 'Meet with one of the expert mentors for a code review of the pull request you were working on this morning. Lots of great feedback you can start on in the morning!', + ), + ], + ); + } + Widget _buildTimelineItem( + {required String time, + required String title, + required String description}) { + return TimelineTile( + alignment: TimelineAlign.start, + isFirst: true, + indicatorStyle: const IndicatorStyle( + width: 40.0, + color: Colors.orange, + padding: EdgeInsets.all(8.0), + ), + endChild: Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + time, + style: const TextStyle( + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 8.0), + Text( + title, + style: const TextStyle( + fontSize: 18.0, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 4.0), + Text(description), + ], + ), + ), + ); + } +} + +class TrackDetailsScreen extends StatelessWidget { + final String title, description; + final String? url; + + const TrackDetailsScreen( + {super.key, required this.title, required this.description, this.url}); - body: const Center( - child: Text('MajorLeagueHackingFellowship'), + @override + Widget build(BuildContext context) { + double screenWidth = MediaQuery.of(context).size.width; + double gap = screenWidth * 0.05; + double pad = screenWidth * 0.04; + double titleSize = screenWidth * 0.05; + double contentSize = screenWidth * 0.04; + return Scaffold( + appBar: AppBar( + title: Text(title), + ), + body: SingleChildScrollView( + padding: EdgeInsets.all(pad), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.symmetric(vertical: pad), + child: Text( + title, + style: + TextStyle(fontSize: titleSize, fontWeight: FontWeight.bold), + ), + ), + SizedBox(height: gap), + Padding( + padding: EdgeInsets.symmetric(vertical: pad), + child: Text( + description, + style: TextStyle( + fontSize: contentSize, + ), + ), + ), + SizedBox(height: gap), + (url != null && url!.isNotEmpty) + ? Center( + child: ElevatedButton( + onPressed: () { + _launchUrl(url!); + }, + child: const Text('Explore More'), + ), + ) + : Container(), + ], ), ), ); } } +Future _launchUrl(String url) async { + final Uri uri = Uri.parse(url); + if (!await launchUrl(uri)) { + throw 'Could not launch $url'; + } +} diff --git a/lib/programs screen/open_summer_of_code.dart b/lib/programs screen/open_summer_of_code.dart new file mode 100644 index 0000000..3866ad1 --- /dev/null +++ b/lib/programs screen/open_summer_of_code.dart @@ -0,0 +1,332 @@ +import 'dart:convert'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:opso/modals/osoc_modal.dart'; +import 'package:opso/widgets/osoc_widget.dart'; +import 'package:opso/widgets/year_button.dart'; +import 'package:opso/programs_info_pages/osoc_info.dart'; +import '../modals/book_mark_model.dart'; +import '../widgets/SearchandFilterWidget.dart'; + +class OpenSummerOfCode extends StatefulWidget { + const OpenSummerOfCode({super.key}); + + @override + State createState() => _OpenSummerOfCodeState(); +} + +class _OpenSummerOfCodeState extends State { + List osoc2022 = []; + List osoc2021 = []; + String currectPage = "/open_summer_of_code"; + String currentProject = "Open Summer of Code"; + bool isBookmarked = true; + int selectedYear = 2022; + + List projectList = []; + Future? getProjectFunction; + + Future initializeProjectLists() async { + var response = + await rootBundle.loadString('assets/projects/osoc/osoc2022.json'); + var jsonList = await json.decode(response); + for (var data in jsonList) { + osoc2022.add(OsocModal.fromMap(data)); + } + projectList = osoc2022; + print(projectList); + response = + await rootBundle.loadString('assets/projects/osoc/osoc2021.json'); + jsonList = await json.decode(response); + for (var data in jsonList) { + osoc2021.add(OsocModal.fromMap(data)); + } + } + + @override + void initState() { + getProjectFunction = initializeProjectLists(); + super.initState(); + _checkBookmarkStatus(); + } + + Future _checkBookmarkStatus() async { + bool bookmarkStatus = await HandleBookmark.isBookmarked(currentProject); + setState(() { + isBookmarked = bookmarkStatus; + }); + } + + void searchTag(String searchTag) { + projectList = projectList + .where((OsocModal element) => element.name.contains(searchTag)) + .toList(); + setState(() {}); + } + + void search(String searchText) { + if (searchText.isEmpty) { + switch (selectedYear) { + case 2021: + projectList = osoc2021; + break; + case 2022: + projectList = osoc2022; + break; + } + setState(() {}); + return; + } + searchText = searchText.toLowerCase(); + projectList = projectList + .where((OsocModal element) => + element.name.toLowerCase().contains(searchText) || + element.description.toLowerCase().contains(searchText)) + .toList(); + setState(() {}); + } + + // List languages = [ + // 'Rust miniscript', + // 'Core Lightning', + // 'LDK', + // 'Bitcoin Core', + // 'Alby', + // 'Eye of Satoshi', + // 'Ledger Bitcoin App', + // 'Galoy', + // 'Fedimint', + // 'VLS', + // 'StratumV2', + // 'bcoin', + // 'LND', + // 'Eclair' + // ]; + + Future _refresh() async { + osoc2021.clear(); + osoc2022.clear(); + await initializeProjectLists(); + + selectedYear = 2022; + setState(() {}); + } + + @override + Widget build(BuildContext context) { + var height = MediaQuery.sizeOf(context).height; + var width = MediaQuery.sizeOf(context).width; + const ScreenUtilInit( + designSize: Size(360, 690), + ); + return RefreshIndicator( + onRefresh: _refresh, + child: Scaffold( + appBar: + AppBar(title: const Text('Open Summer of Code'), actions: [ + IconButton( + icon: (isBookmarked) + ? const Icon(Icons.bookmark_add_rounded) + : const Icon(Icons.bookmark_add_outlined), + onPressed: () { + setState(() { + isBookmarked = !isBookmarked; + }); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + isBookmarked ? 'Bookmark added' : 'Bookmark removed'), + duration: const Duration( + seconds: 2), // Adjust the duration as needed + ), + ); + if (isBookmarked) { + print("Adding"); + HandleBookmark.addBookmark(currentProject, currectPage); + } else { + print("Deleting"); + HandleBookmark.deleteBookmark(currentProject); + } + }, + ), + IconButton( + icon: const Icon(Icons.info_outline), + onPressed: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => const OSOCInfo()), + ); + }, + ), + ]), + body: FutureBuilder( + future: getProjectFunction, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + return const Center(child: CircularProgressIndicator()); + } else if (snapshot.connectionState == ConnectionState.done) { + return Padding( + padding: EdgeInsets.symmetric( + horizontal: ScreenUtil().setWidth(46), + vertical: ScreenUtil().setHeight(16)), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + TextFormField( + decoration: InputDecoration( + filled: true, + hintText: 'Search', + suffixIcon: const Icon(Icons.search), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: const BorderSide( + color: Color(0xFFEEEEEE), + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: const BorderSide( + color: Color(0xFFEEEEEE), + ), + ), + disabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: const BorderSide( + color: Color(0xFFEEEEEE), + ), + ), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: const BorderSide( + color: Color(0xFFEEEEEE), + ), + ), + contentPadding: EdgeInsets.symmetric( + vertical: ScreenUtil().setHeight(12), + horizontal: ScreenUtil().setWidth(20)), + ), + onFieldSubmitted: (value) { + search(value.trim()); + }, + onChanged: (value) { + if (value.isEmpty) { + search(value); + } + }, + ), + SizedBox(height: ScreenUtil().setHeight(20)), + SizedBox( + height: height * 0.1, + width: width, + child: GridView( + physics: const NeverScrollableScrollPhysics(), + gridDelegate: + const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + childAspectRatio: 1.5 / 0.6, + crossAxisSpacing: 15, + mainAxisSpacing: 15, + ), + children: [ + YearButton( + year: "2021", + isEnabled: selectedYear == 2021 ? true : false, + onTap: () { + setState(() { + projectList = osoc2021; + selectedYear = 2021; + }); + }, + backgroundColor: selectedYear == 2021 + ? Colors.white + : const Color.fromRGBO(255, 183, 77, 1), + ), + YearButton( + year: "2022", + isEnabled: selectedYear == 2022 ? true : false, + onTap: () { + setState(() { + projectList = osoc2022; + selectedYear = 2022; + }); + }, + backgroundColor: selectedYear == 2022 + ? Colors.white + : const Color.fromRGBO(255, 183, 77, 1), + ), + ], + ), + ), + + // Row( + // crossAxisAlignment: CrossAxisAlignment.center, + // mainAxisAlignment: MainAxisAlignment.spaceEvenly, + // children: [ + // const Text( + // 'Filter by Org:', + // style: TextStyle(fontWeight: FontWeight.w400), + // ), + // Padding( + // padding: EdgeInsets.all(ScreenUtil().setHeight(8)), + // child: Row( + // crossAxisAlignment: CrossAxisAlignment.center, + // mainAxisAlignment: MainAxisAlignment.spaceEvenly, + // children: [ + // DropdownWidget( + // items: languages, + // hintText: 'Org', + // onChanged: (newValue) { + // setState(() { + // switch (selectedYear) { + // case 2021: + // projectList = sob2021; + // break; + // case 2022: + // projectList = sob2022; + // break; + // case 2023: + // projectList = sob2023; + // break; + // } + // searchTag(newValue); + // }); + // // Perform filtering based on selectedLanguage + // }, + // ), + // ], + // ), + // ) + // ], + // ), + // SizedBox( + // height: ScreenUtil().setHeight(20), + // ), + Expanded( + // width: width, + child: ListView.builder( + itemCount: projectList.length, + itemBuilder: (BuildContext context, int index) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 10), + child: OsocWidget( + modal: projectList[index], + height: ScreenUtil().screenHeight * 0.2, + width: ScreenUtil().screenWidth, + ), + ); + }, + ), + ), + ], + ), + ); + } else { + return const Center(child: Text("Some error occured")); + } + }), + ), + ); + } +} diff --git a/lib/programs screen/season_of_kde.dart b/lib/programs screen/season_of_kde.dart new file mode 100644 index 0000000..bf5b722 --- /dev/null +++ b/lib/programs screen/season_of_kde.dart @@ -0,0 +1,285 @@ +import 'dart:convert'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:opso/modals/book_mark_model.dart'; +import 'package:opso/modals/sokde_project_modal.dart'; +import 'package:opso/programs_info_pages/sokde_info.dart'; +import 'package:opso/widgets/sokde_project_widget.dart'; +import 'package:opso/widgets/small_year_button.dart'; + +class SeasonOfKDE extends StatefulWidget { + const SeasonOfKDE({super.key}); + + @override + _SeasonOfKDEState createState() => _SeasonOfKDEState(); +} + +class _SeasonOfKDEState extends State { + List sokde2024 = []; + List sokde2023 = []; + List sokde2022 = []; + String currectPage = "/season_of_kde"; + String currentProject = "Season of KDE"; + bool isBookmarked = true; + int selectedYear = 2024; + + List projectList = []; + late Future getProjectFunction; + + Future initializeProjectLists() async { + var response = + await rootBundle.loadString('assets/projects/sokde/sokde2024.json'); + var jsonList = await json.decode(response); + for (var data in jsonList) { + sokde2024.add(SokdeProjectModal.fromJson(data)); + } + projectList = sokde2024; + print(projectList); + response = + await rootBundle.loadString('assets/projects/sokde/sokde2023.json'); + jsonList = await json.decode(response); + for (var data in jsonList) { + sokde2023.add(SokdeProjectModal.fromJson(data)); + } + response = + await rootBundle.loadString('assets/projects/sokde/sokde2022.json'); + jsonList = await json.decode(response); + for (var data in jsonList) { + sokde2022.add(SokdeProjectModal.fromJson(data)); + } +} + + + @override + void initState() { + super.initState(); + getProjectFunction = initializeProjectLists(); + _checkBookmarkStatus(); + } + + Future _checkBookmarkStatus() async { + bool bookmarkStatus = await HandleBookmark.isBookmarked(currentProject); + setState(() { + isBookmarked = bookmarkStatus; + }); + } + + void searchTag(String searchTag) { + projectList = projectList + .where((element) => element.name.toLowerCase().contains(searchTag)) + .toList(); + setState(() {}); + } + + void search(String searchText) { + if (searchText.isEmpty) { + switch (selectedYear) { + case 2024: + projectList = sokde2024; + break; + case 2023: + projectList = sokde2023; + break; + case 2022: + projectList = sokde2022; + break; + } + setState(() {}); + return; + } + searchText = searchText.toLowerCase(); + projectList = projectList + .where((element) => + element.name.toLowerCase().contains(searchText) || + element.mentors.contains(searchText)) + .toList(); + setState(() {}); + } + + Future _refresh() async { + sokde2023.clear(); + sokde2024.clear(); + sokde2022.clear(); + await initializeProjectLists(); + + setState(() {}); + } + + @override + Widget build(BuildContext context) { + return RefreshIndicator( + onRefresh: _refresh, + child: Scaffold( + appBar: AppBar( + title: const Text('Season of KDE'), + actions: [ + IconButton( + icon: Icon( + isBookmarked + ? Icons.bookmark_add_rounded + : Icons.bookmark_add_outlined, + ), + onPressed: () { + setState(() { + isBookmarked = !isBookmarked; + }); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + isBookmarked ? 'Bookmark added' : 'Bookmark removed', + ), + duration: const Duration(seconds: 2), + ), + ); + if (isBookmarked) { + HandleBookmark.addBookmark(currentProject, currectPage); + } else { + HandleBookmark.deleteBookmark(currentProject); + } + }, + ), + IconButton( + icon: const Icon(Icons.info_outline), + onPressed: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => const SOKDEInfo()), + ); + }, + ), + ], + ), + body: FutureBuilder( + future: getProjectFunction, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + return const Center(child: CircularProgressIndicator()); + } else if (snapshot.hasError) { + return Center(child: Text("Error: ${snapshot.error}")); + } else if (snapshot.connectionState == ConnectionState.done) { + return Padding( + padding: EdgeInsets.symmetric( + horizontal: ScreenUtil().setWidth(46), + vertical: ScreenUtil().setHeight(16), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + TextFormField( + decoration: InputDecoration( + filled: true, + hintText: 'Search', + suffixIcon: const Icon(Icons.search), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: const BorderSide(color: Color(0xFFEEEEEE)), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: const BorderSide(color: Color(0xFFEEEEEE)), + ), + disabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: const BorderSide(color: Color(0xFFEEEEEE)), + ), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: const BorderSide(color: Color(0xFFEEEEEE)), + ), + contentPadding: EdgeInsets.symmetric( + vertical: ScreenUtil().setHeight(12), + horizontal: ScreenUtil().setWidth(20), + ), + ), + onFieldSubmitted: (value) { + search(value.trim()); + }, + onChanged: (value) { + if (value.isEmpty) { + search(value); + } + }, + ), + SizedBox(height: ScreenUtil().setHeight(20)), + SizedBox( + height: MediaQuery.of(context).size.height * 0.1, + child: GridView( + physics: const NeverScrollableScrollPhysics(), + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 3, + childAspectRatio: 3, + crossAxisSpacing: 15, + mainAxisSpacing: 15, + ), + children: [ + YearButton( + year: "2024", + isEnabled: selectedYear == 2024, + onTap: () { + setState(() { + projectList = sokde2024; + selectedYear = 2024; + }); + }, + backgroundColor: selectedYear == 2024 + ? Colors.white + : const Color.fromRGBO(255, 183, 77, 1), + ), + YearButton( + year: "2023", + isEnabled: selectedYear == 2023, + onTap: () { + setState(() { + projectList = sokde2023; + selectedYear = 2023; + }); + }, + backgroundColor: selectedYear == 2023 + ? Colors.white + : const Color.fromRGBO(255, 183, 77, 1), + ), + YearButton( + year: "2022", + isEnabled: selectedYear == 2022, + onTap: () { + setState(() { + projectList = sokde2022; + selectedYear = 2022; + }); + }, + backgroundColor: selectedYear == 2022 + ? Colors.white + : const Color.fromRGBO(255, 183, 77, 1), + ), + ], + ), + ), + Expanded( + child: ListView.builder( + itemCount: projectList.length, + itemBuilder: (BuildContext context, int index) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 10), + child: SokdeProjectWidget( + modal: projectList[index], + height: ScreenUtil().screenHeight * 0.2, + width: ScreenUtil().screenWidth, + index: index, + ), + ); + }, + ), + ), + ], + ), + ); + } else { + return const Center(child: Text("Some error occurred")); + } + }, + ), + ), + ); + } +} diff --git a/lib/programs screen/social_winter_of_code.dart b/lib/programs screen/social_winter_of_code.dart index 9857277..9bf93cb 100644 --- a/lib/programs screen/social_winter_of_code.dart +++ b/lib/programs screen/social_winter_of_code.dart @@ -5,6 +5,7 @@ import 'package:multi_select_flutter/dialog/multi_select_dialog_field.dart'; import 'package:multi_select_flutter/util/multi_select_item.dart'; import 'package:opso/modals/book_mark_model.dart'; import 'package:opso/modals/swoc_project_modal.dart'; +import 'package:opso/programs_info_pages/swoc_info.dart'; import 'package:opso/widgets/swoc_project_widget.dart'; import 'package:opso/widgets/year_button.dart'; @@ -220,7 +221,15 @@ class _SWOCScreenState extends State { HandleBookmark.deleteBookmark(currentProject); } }, - ) + ), + IconButton( + icon: Icon(Icons.info_outline), + onPressed: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => SWOCInfo()), ); + }, + ), ]), body: FutureBuilder( future: getProjectFunction, diff --git a/lib/programs screen/summer_of_bitcoin.dart b/lib/programs screen/summer_of_bitcoin.dart index eb08795..9c0a5bc 100644 --- a/lib/programs screen/summer_of_bitcoin.dart +++ b/lib/programs screen/summer_of_bitcoin.dart @@ -3,6 +3,7 @@ import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:opso/modals/sob_project_modal.dart'; +import 'package:opso/programs_info_pages/sob_info.dart'; import 'package:opso/widgets/sob_project_widget.dart'; import 'package:opso/widgets/year_button.dart'; @@ -158,7 +159,16 @@ class _SummerOfBitcoinState extends State { HandleBookmark.deleteBookmark(currentProject); } }, - ) + ), + IconButton( + icon: const Icon(Icons.info_outline), + onPressed: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => const SOBInfo()), + ); + }, + ), ]), body: FutureBuilder( future: getProjectFunction, diff --git a/lib/programs_info_pages/gsoc_info.dart b/lib/programs_info_pages/gsoc_info.dart new file mode 100644 index 0000000..d4a5a1c --- /dev/null +++ b/lib/programs_info_pages/gsoc_info.dart @@ -0,0 +1,201 @@ +import 'package:flutter/material.dart'; +import 'package:timeline_tile/timeline_tile.dart'; + +class GSOCInfo extends StatelessWidget { + const GSOCInfo({super.key}); + + @override + Widget build(BuildContext context) { + final List> events = [ + {'date': 'February 21 - 18:00 UTC', 'description': 'List of accepted mentoring organizations published'}, + {'date': 'February 22 - March 18', 'description': 'Potential GSoC contributors discuss application ideas with mentoring organizations'}, + {'date': 'March 18 - 18:00 UTC', 'description': 'GSoC contributor application period begins'}, + {'date': 'April 2 - 18:00 UTC', 'description': 'GSoC contributor application deadline'}, + {'date': 'April 24 - 18:00 UTC', 'description': 'GSoC contributor proposal rankings due from Org Admins'}, + {'date': 'May 1 - 18:00 UTC', 'description': 'Accepted GSoC contributor projects announced'}, + {'date': 'May 1 - 26', 'description': 'Community Bonding Period | GSoC contributors get to know mentors, read documentation, get up to speed to begin working on their projects'}, + {'date': 'May 27', 'description': 'Coding officially begins!'}, + {'date': 'July 8 - 18:00 UTC', 'description': 'Mentors and GSoC contributors can begin submitting midterm evaluations'}, + {'date': 'August 19 - 26 - 18:00 UTC', 'description': 'Final week: GSoC contributors submit their final work product and their final mentor evaluation (standard coding period)'}, + {'date': 'August 26 - September 2 - 18:00 UTC', 'description': 'Mentors submit final GSoC contributor evaluations (standard coding period)'}, + {'date': 'September 3', 'description': 'Initial results of Google Summer of Code 2024 announced'}, + {'date': 'September 3 - November 4', 'description': 'GSoC contributors with extended timelines continue coding'}, + {'date': 'November 4 - 18:00 UTC', 'description': 'Final date for all GSoC contributors to submit their final work product and final evaluation'}, + ]; + + return Scaffold( + appBar: AppBar( + title: const Text('Project Information'), + ), + body: Padding( + padding: const EdgeInsets.all(10.0), + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Google Summer Of Code', + style: Theme.of(context).textTheme.titleLarge, + ), + const SizedBox(height: 20), + _buildOutlinedBox( + context, + title: 'Overview', + content: 'Google Summer of Code is a global, online program focused on bringing new contributors into open source software development. GSoC Contributors work with an open source organization on a 12+ week programming project under the guidance of mentors.', + ), + const SizedBox(height: 20), + _buildOutlinedBox( + context, + title: 'Eligibility : What are the eligibility requirements for participation?', + content: + '> You must be at least 18 years of age when you register.\n' + '> You must be eligible to work in the country you will reside in during the program.\n' + '> You must be an open source beginner or a student.\n' + '> You have not been accepted as a GSoC Contributor/Student in GSoC more than once.\n' + '> You must reside in a country that is not currently embargoed by the United States.', + ), + const SizedBox(height: 20), + Text( + 'Program Timeline', + style: Theme.of(context).textTheme.headlineSmall, + ), + const SizedBox(height: 10), + _buildTimeline(events), + const SizedBox(height: 20), + Text( + 'Prizes and Rewards', + style: Theme.of(context).textTheme.headlineSmall, + ), + const SizedBox(height: 10), + Column( + children: [ + _buildPrizeBox( + context, + 'Google will provide a stipend to GSoC Contributors who pass their evaluations and are able to receive stipends.', + ), + const SizedBox(height: 10), + _buildPrizeBox( + context, + 'Google will also provide a Certificate of Completion to GSoC Contributors who pass their evaluations.', + ), + ], + ), + ], + ), + ), + ), + ); + } + + Widget _buildOutlinedBox(BuildContext context, {required String title, required String content}) { + return Container( + padding: const EdgeInsets.all(10.0), + decoration: BoxDecoration( + border: Border.all(color: Colors.orange, width: 1.0), + borderRadius: BorderRadius.circular(8.0), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: Theme.of(context).textTheme.headlineSmall, + ), + const SizedBox(height: 10), + Text( + content, + style: Theme.of(context).textTheme.bodyLarge, + ), + ], + ), + ); + } + + Widget _buildTimeline(List> events) { + return Column( + children: events.asMap().entries.map((entry) { + int index = entry.key; + Map event = entry.value; + final bool isFirst = index == 0; + final bool isLast = index == events.length - 1; + final bool isLeft = index % 2 == 0; + + return TimelineTile( + axis: TimelineAxis.vertical, + alignment: TimelineAlign.center, + isFirst: isFirst, + isLast: isLast, + beforeLineStyle: const LineStyle( + color: Colors.orange, + thickness: 4, + ), + afterLineStyle: const LineStyle( + color: Colors.orange, + thickness: 4, + ), + indicatorStyle: IndicatorStyle( + indicator: Container( + decoration: const BoxDecoration( + color: Colors.orange, + shape: BoxShape.circle, + ), + child: const Icon( + Icons.event, + size: 15, + color: Colors.white, + ), + ), + ), + startChild: isLeft ? _buildEventChild(event) : null, + endChild: isLeft ? null : _buildEventChild(event), + ); + }).toList(), + ); + } + + Widget _buildEventChild(Map event) { + return Container( + width: 150, + margin: const EdgeInsets.all(10), + padding: const EdgeInsets.all(10), + decoration: BoxDecoration( + color: Colors.orange, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + event['date'], + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 16, + ), + ), + const SizedBox(height: 8), + Text( + event['description'], + style: const TextStyle( + fontSize: 14, + ), + ), + ], + ), + ); + } + + Widget _buildPrizeBox(BuildContext context, String description) { + return Container( + padding: const EdgeInsets.all(10.0), + decoration: BoxDecoration( + border: Border.all(color: Colors.orange, width: 1.0), + borderRadius: BorderRadius.circular(8), + ), + child: Text( + description, + textAlign: TextAlign.center, + style: Theme.of(context).textTheme.bodyLarge, + ), + ); + } +} diff --git a/lib/programs_info_pages/gsod_info.dart b/lib/programs_info_pages/gsod_info.dart new file mode 100644 index 0000000..5f395ed --- /dev/null +++ b/lib/programs_info_pages/gsod_info.dart @@ -0,0 +1,198 @@ +import 'package:flutter/material.dart'; +import 'package:timeline_tile/timeline_tile.dart'; + +class GSODInfo extends StatelessWidget { + const GSODInfo({super.key}); + + @override + Widget build(BuildContext context) { + final List> events = [ + {'date': 'February 2, 2024', 'description': 'Google Season of Docs program announced'}, + {'date': 'April 10, 2024 at 18:00 UTC', 'description': 'Google publishes the list of accepted organizations'}, + {'date': 'April 10, 2024', 'description': 'Doc development can officially begin'}, + {'date': 'April 10 - November 22, 2024', 'description': 'Hired technical writers work on documentation projects with guidance from organizations'}, + {'date': 'May 22, 2024 at 18:00 UTC', 'description': 'Technical writer hiring deadline'}, + {'date': 'June 5, 2024 - June 12, 2024 at 18:00 UTC', 'description': 'First monthly evaluation period. Organization administrators submit first of four monthly evaluation forms'}, + {'date': 'July 5, 2024 - July 12, 2024 at 18:00 UTC', 'description': 'Second monthly evaluation period'}, + {'date': 'September 5, 2024 - September 12, 2024 at 18:00 UTC', 'description': 'Third monthly evaluation period'}, + {'date': 'October 22, 2024 - October 29, 2024 at 18:00 UTC', 'description': 'Fourth monthly evaluation period'}, + {'date': 'November 22, 2024 - December 10, 2024 at 18:00 UTC', 'description': 'Organization administrators submit their case study and final project evaluation'}, + {'date': 'December 13, 2024', 'description': 'Google publishes the 2024 Google Season of Docs case studies and aggregate project data'}, + ]; + + return Scaffold( + appBar: AppBar( + title: const Text('Project Information'), + ), + body: Padding( + padding: const EdgeInsets.all(10.0), + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Google Season Of Docs', + style: Theme.of(context).textTheme.titleLarge, + ), + const SizedBox(height: 20), + _buildOutlinedBox( + context, + title: 'Overview', + content: 'Google Season of Docs provides support for open source projects to improve their documentation and gives professional technical writers an opportunity to gain experience in open source. Together we raise awareness of open source, of docs, and of technical writing.', + ), + const SizedBox(height: 20), + _buildOutlinedBox( + context, + title: 'Eligibility : What are the eligibility requirements for participation?', + content: + '(a) run an active and viable open source software project.\n' + '(b) have already produced and released software under an Open Source Initiative (OSI)-approved license.\n' + '(c) not be a government agency or acting on behalf of a government or quasi-government agency that is funded by the public.\n' + '(d) not be based in a United States embargoed country, or otherwise prohibited by applicable export controls and sanctions programs.\n' + '(e) if the Organization is an individual, \n(i) not be a resident of a United States embargoed country; \n(ii) not be ordinarily resident in a United States embargoed country, or otherwise prohibited by applicable export controls and sanctions programs; and \n(iii) be at least eighteen (18) years of age upon registration for the Program.', + ), + const SizedBox(height: 20), + Text( + 'Program Timeline', + style: Theme.of(context).textTheme.headlineSmall, + ), + const SizedBox(height: 10), + _buildTimeline(events), + const SizedBox(height: 20), + Text( + 'Prizes and Rewards', + style: Theme.of(context).textTheme.headlineSmall, + ), + const SizedBox(height: 10), + Column( + children: [ + _buildPrizeBox( + context, + 'Each project will receive 5,000 - 15,000 USD. The amount your organization receives will be based on the needs of your documentation project.', + ), + const SizedBox(height: 10), + _buildPrizeBox( + context, + 'By participating in GSoD, you will receive a Google certificate that will add prestigious credentials to your resume and set you apart from the crowd in the tech industry. It will highlight your expertise and commitment to excellence in technical writing.', + ), + ], + ), + ], + ), + ), + ), + ); + } + + Widget _buildOutlinedBox(BuildContext context, {required String title, required String content}) { + return Container( + padding: const EdgeInsets.all(10.0), + decoration: BoxDecoration( + border: Border.all(color: Colors.orange, width: 1.0), + borderRadius: BorderRadius.circular(8.0), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: Theme.of(context).textTheme.headlineSmall, + ), + const SizedBox(height: 10), + Text( + content, + style: Theme.of(context).textTheme.bodyLarge, + ), + ], + ), + ); + } + + Widget _buildTimeline(List> events) { + return Column( + children: events.asMap().entries.map((entry) { + int index = entry.key; + Map event = entry.value; + final bool isFirst = index == 0; + final bool isLast = index == events.length - 1; + final bool isLeft = index % 2 == 0; + + return TimelineTile( + axis: TimelineAxis.vertical, + alignment: TimelineAlign.center, + isFirst: isFirst, + isLast: isLast, + beforeLineStyle: const LineStyle( + color: Colors.orange, + thickness: 4, + ), + afterLineStyle: const LineStyle( + color: Colors.orange, + thickness: 4, + ), + indicatorStyle: IndicatorStyle( + indicator: Container( + decoration: const BoxDecoration( + color: Colors.orange, + shape: BoxShape.circle, + ), + child: const Icon( + Icons.event, + size: 15, + color: Colors.white, + ), + ), + ), + startChild: isLeft ? _buildEventChild(event) : null, + endChild: isLeft ? null : _buildEventChild(event), + ); + }).toList(), + ); + } + + Widget _buildEventChild(Map event) { + return Container( + width: 150, + margin: const EdgeInsets.all(10), + padding: const EdgeInsets.all(10), + decoration: BoxDecoration( + color: Colors.orange, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + event['date'], + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 16, + ), + ), + const SizedBox(height: 8), + Text( + event['description'], + style: const TextStyle( + fontSize: 14, + ), + ), + ], + ), + ); + } + + Widget _buildPrizeBox(BuildContext context, String description) { + return Container( + padding: const EdgeInsets.all(10.0), + decoration: BoxDecoration( + border: Border.all(color: Colors.orange, width: 1.0), + borderRadius: BorderRadius.circular(8), + ), + child: Text( + description, + textAlign: TextAlign.center, + style: Theme.of(context).textTheme.bodyLarge, + ), + ); + } +} diff --git a/lib/programs_info_pages/gssoc_info.dart b/lib/programs_info_pages/gssoc_info.dart new file mode 100644 index 0000000..d7ea586 --- /dev/null +++ b/lib/programs_info_pages/gssoc_info.dart @@ -0,0 +1,226 @@ +import 'package:flutter/material.dart'; +import 'package:timeline_tile/timeline_tile.dart'; + +class GSSOCInfo extends StatelessWidget { + const GSSOCInfo({super.key}); + + @override + Widget build(BuildContext context) { + final List> events = [ + {'date': '5th-6th May', 'description': 'Project Assignment to Mentors.'}, + {'date': '10th May', 'description': 'Coding period begins!'}, + {'date': '20th May', 'description': 'Community bonding period starts!'}, + {'date': '30th May', 'description': 'Leaderboard Opens.'}, + {'date': '30th July', 'description': 'Coding period ends.'}, + {'date': '2nd week of August', 'description': 'Results will be declared.'}, + ]; + + + return Scaffold( + appBar: AppBar( + title: const Text('Project Information'), + ), + body: Padding( + padding: const EdgeInsets.all(10.0), + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'GirlScript Summer of Code', + style: Theme.of(context).textTheme.titleLarge, + ), + const SizedBox(height: 20), + _buildOutlinedBox( + context, + title: 'Overview', + content: 'GirlScript Summer Of Code is a three-month-long Open-Source Program conducted every summer by the Girlscript Foundation. With constant efforts, participants contribute to numerous projects under the extreme guidance of skilled mentors over these months. With such exposure, students begin to contribute to real-world projects from the comfort of their homes.', + ), + const SizedBox(height: 20), + _buildOutlinedBox( + context, + title: 'Eligibility', + content: 'Is there any registration fees?\n' + 'No, there’s no registration fees. It is absolutely free for participants.\n\n' + 'Will a beginner, with absolutely no knowledge of github, gain anything fruitful?\n' + 'Yeah, definitely. The organization is meant to assist the beginners grow in the field of development. We will have distinct projects appropriate both for beginners as well as the accolades and thereby we will make sure that each and every participant gets to learn something new from the projects he or she is contributing for.\n\n' + 'Any age limit for participation?\n' + 'No, there is no age limit for participation in GSSoC. It is open for all.', + ), + + const SizedBox(height: 20), + Text( + 'Program Timeline', + style: Theme.of(context).textTheme.headlineSmall, + ), + const SizedBox(height: 10), + _buildTimeline(events), + const SizedBox(height: 20), + Text( + 'Prizes and Rewards', + style: Theme.of(context).textTheme.headlineSmall, + ), + const SizedBox(height: 10), + Center( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + children: [ + Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: _buildPrizeBox( + context, + 'Top 3 contributors will be receiving\n - Cash Prizes\n - Certificate of Appreciation\n - Cool T-Shirts & Schwag Kit\n - Internship Opportunities\n - Shoutout on Socials\n - Subscriptions and perks from our partners', + ), + ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: _buildPrizeBox( + context, + 'Top 10 contributors will be receiving\n - Certificate of Appreciation\n - Cool T-Shirts & Schwag Kit\n - Internship Opportunities\n - Shoutout on Socials\n - Subscriptions and perks from our partners', + ), + ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: _buildPrizeBox( + context, + 'Top 25 contributors will be receiving\n - Certificate of Appreciation\n - Cool T-Shirts & Schwag Kit\n - Shoutout on Socials\n - Subscriptions and perks from our partners', + ), + ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: _buildPrizeBox( + context, + 'Top 50 contributors will be receiving\n - Certificate of Appreciation\n - Shoutout on Socials\n - Subscriptions and perks from our partners', + ), + ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: _buildPrizeBox( + context, + 'Top 100 contributors will be receiving\n - Certificate of Appreciation\n - Shoutout on Socials\n - Subscriptions and perks from our partners', + ), + ), + ], + ), + ), + ), + ], + ), + ), + ), + ); + } + + Widget _buildOutlinedBox(BuildContext context, {required String title, required String content}) { + return Container( + padding: const EdgeInsets.all(10.0), + decoration: BoxDecoration( + border: Border.all(color: Colors.orange, width: 1.0), + borderRadius: BorderRadius.circular(8.0), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: Theme.of(context).textTheme.headlineSmall, + ), + const SizedBox(height: 10), + Text( + content, + style: Theme.of(context).textTheme.bodyLarge, + ), + ], + ), + ); + } + + Widget _buildTimeline(List> events) { + return Column( + children: events.asMap().entries.map((entry) { + int index = entry.key; + Map event = entry.value; + final bool isFirst = index == 0; + final bool isLast = index == events.length - 1; + final bool isLeft = index % 2 == 0; + + return TimelineTile( + axis: TimelineAxis.vertical, + alignment: TimelineAlign.center, + isFirst: isFirst, + isLast: isLast, + beforeLineStyle: const LineStyle( + color: Colors.orange, + thickness: 4, + ), + afterLineStyle: const LineStyle( + color: Colors.orange, + thickness: 4, + ), + indicatorStyle: IndicatorStyle( + indicator: Container( + decoration: const BoxDecoration( + color: Colors.orange, + shape: BoxShape.circle, + ), + child: const Icon( + Icons.event, + size: 15, + color: Colors.white, + ), + ), + ), + startChild: isLeft ? _buildEventChild(event) : null, + endChild: isLeft ? null : _buildEventChild(event), + ); + }).toList(), + ); + } + + Widget _buildEventChild(Map event) { + return Container( + width: 150, + margin: const EdgeInsets.all(10), + padding: const EdgeInsets.all(10), + decoration: BoxDecoration( + color: Colors.orange, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + event['date'], + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 16, + ), + ), + const SizedBox(height: 8), + Text( + event['description'], + style: const TextStyle( + fontSize: 14, + ), + ), + ], + ), + ); + } + + Widget _buildPrizeBox(BuildContext context, String description) { + return Container( + padding: const EdgeInsets.all(10.0), + decoration: BoxDecoration( + border: Border.all(color: Colors.orange, width: 1.0), + borderRadius: BorderRadius.circular(8), + ), + child: Text( + description, + textAlign: TextAlign.center, + style: Theme.of(context).textTheme.bodyLarge, + ), + ); + } +} diff --git a/lib/programs_info_pages/linux_info.dart b/lib/programs_info_pages/linux_info.dart new file mode 100644 index 0000000..cf9a2d1 --- /dev/null +++ b/lib/programs_info_pages/linux_info.dart @@ -0,0 +1,118 @@ +import 'package:flutter/material.dart'; + +class LINUXInfo extends StatelessWidget { + const LINUXInfo({super.key}); + + @override + Widget build(BuildContext context) { + + + return Scaffold( + appBar: AppBar( + title: const Text('Project Information'), + ), + body: Padding( + padding: const EdgeInsets.all(10.0), + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Linux Foundation Mentorship Program', + style: Theme.of(context).textTheme.titleLarge, + ), + const SizedBox(height: 20), + _buildOutlinedBox( + context, + title: 'Overview', + content: 'The Linux Foundation Mentorship Program is designed to help developers — many of whom are first-time open source contributors — with necessary skills and resources to learn, experiment, and contribute effectively to open source communities. By participating in a mentorship program, mentees have the opportunity to learn from experienced open source contributors as a segue to get internship and job opportunities upon graduation.', + ), + const SizedBox(height: 20), + _buildOutlinedBox( + context, + title: 'Eligibility Criteria', + content: 'The following eligibility rules apply to all mentee applicants:\n\n' + '1. Be at least 18 years old by the time the mentorship program starts.\n\n' + '2. Not be a prior or an active participant in another Linux Foundation mentorship program.\n\n' + '3. Be eligible to work in the country and jurisdiction where you will be participating in the Mentorship program.\n\n' + '4. Not reside in a country or jurisdiction where participation in the mentorship is prohibited under applicable U.S. federal, state or local laws or the laws of other countries.\n\n' + '5. Seeking to participate on your own behalf as an individual.\n\n' + '6. Not be subject to any existing obligations to third parties (such as contractual obligations to an employer) that would restrict or prohibit your participation in a mentorship program.\n\n' + '7. Meet all criteria set by the program to which a mentees is applying, i.e. any custom prerequisites and requirements.\n\n' + '8. Not be a maintainer, recurring contributor, etc.. with more than minimal involvement with the open source project that offers a mentorship program.', + ), + const SizedBox(height: 20), + Text( + 'Prizes and Rewards', + style: Theme.of(context).textTheme.headlineSmall, + ), + const SizedBox(height: 10), + Center( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + children: [ + Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: _buildPrizeBox( + context, + 'Get paid while learning\n Mentees are eligible to receive a stipend, which is paid in two installments, provided that regular interval evaluations show you are making satisfactory progress. The final installment will be paid upon successful mentorship completion.', + ), + ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: _buildPrizeBox( + context, + 'Get Hired\n After you successfully complete the mentorship program, get connected to potential employers who are focused on your project and are offering interview opportunities. Your mentor may also refer you to a company.', + ), + ), + ], + ), + ), + ), + ], + ), + ), + ), + ); + } + + Widget _buildOutlinedBox(BuildContext context, {required String title, required String content}) { + return Container( + padding: const EdgeInsets.all(10.0), + decoration: BoxDecoration( + border: Border.all(color: Colors.orange, width: 1.0), + borderRadius: BorderRadius.circular(8.0), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: Theme.of(context).textTheme.headlineSmall, + ), + const SizedBox(height: 10), + Text( + content, + style: Theme.of(context).textTheme.bodyLarge, + ), + ], + ), + ); + } + + Widget _buildPrizeBox(BuildContext context, String description) { + return Container( + padding: const EdgeInsets.all(10.0), + decoration: BoxDecoration( + border: Border.all(color: Colors.orange, width: 1.0), + borderRadius: BorderRadius.circular(8), + ), + child: Text( + description, + textAlign: TextAlign.center, + style: Theme.of(context).textTheme.bodyLarge, + ), + ); + } +} diff --git a/lib/programs_info_pages/osoc_info.dart b/lib/programs_info_pages/osoc_info.dart new file mode 100644 index 0000000..3db19c6 --- /dev/null +++ b/lib/programs_info_pages/osoc_info.dart @@ -0,0 +1,130 @@ +import 'package:flutter/material.dart'; + +class OSOCInfo extends StatelessWidget { + const OSOCInfo({super.key}); + + @override + Widget build(BuildContext context) { + + return Scaffold( + appBar: AppBar( + title: const Text('Project Information'), + ), + body: Padding( + padding: const EdgeInsets.all(10.0), + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Open Summer of Code', + style: Theme.of(context).textTheme.titleLarge, + ), + const SizedBox(height: 20), + _buildOutlinedBox( + context, + title: 'Overview', + content: 'A 4-week summer programme in July, that provides Belgian based students the training, network and support necessary to transform open innovation projects into powerful real-world services.', + ), + const SizedBox(height: 20), + _buildOutlinedBox( + context, + title: 'When & Where?', + content: '1 July — 25 July From Monday to Thursday, 9AM to 5PM. On Mondays and Thursdays, we work in Brussels, on Tuesdays and Wednesdays we work remotely. You dont have to work on Fridays and weekends! You are off during holidays, but still paid!', + ), + const SizedBox(height: 20), + _buildOutlinedBox( + context, + title: 'Can I participate in OSOC?', + content: 'Yes, if you meet the following requirements.\n' + '* For international students, check the next question\n\n' + 'First of all, you’re a student eligible to work under a student contract for 16 full days (128 hours).\n' + 'Secondly, you study or have experience in front- or back-end development, design (UX, graphic), communication or business modelling.\n' + 'Thirdly, you should be able to express yourself in English.\n' + 'Do you meet these requirements? Congratulations, you could be an OSOC student!', + ), + const SizedBox(height: 20), + _buildOutlinedBox( + context, + title: 'Can I participate if I am not a Belgian citizen?', + content: 'Students from an EEA member state or from Switzerland are entitled to work in Belgium throughout the year under the same terms as Belgian students. EAA member state means any of the member states of the European Union, Iceland, Liechtenstein, and Norway.\n\n' + 'Are you from a country that is not included in the above list? Then you may work in Belgium if you:\n' + 'are registered in education with full curriculum in Belgium\n' + 'have a valid residence permit\n' + 'You must be able to work from 9 to 5 in the GMT+2 time zone.', + ), + const SizedBox(height: 20), + Text( + 'Prizes and Rewards', + style: Theme.of(context).textTheme.headlineSmall, + ), + const SizedBox(height: 10), + Center( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + children: [ + Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: _buildPrizeBox( + context, + 'Get paid for your work! Even on holidays!', + ), + ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: _buildPrizeBox( + context, + 'Certificate of participation and a reference letter from the OSOC team.', + ), + ), + ], + ), + ), + ), + ], + ), + ), + ), + ); + } + + Widget _buildOutlinedBox(BuildContext context, {required String title, required String content}) { + return Container( + padding: const EdgeInsets.all(10.0), + decoration: BoxDecoration( + border: Border.all(color: Colors.orange, width: 1.0), + borderRadius: BorderRadius.circular(8.0), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: Theme.of(context).textTheme.headlineSmall, + ), + const SizedBox(height: 10), + Text( + content, + style: Theme.of(context).textTheme.bodyLarge, + ), + ], + ), + ); + } + + Widget _buildPrizeBox(BuildContext context, String description) { + return Container( + padding: const EdgeInsets.all(10.0), + decoration: BoxDecoration( + border: Border.all(color: Colors.orange, width: 1.0), + borderRadius: BorderRadius.circular(8), + ), + child: Text( + description, + textAlign: TextAlign.center, + style: Theme.of(context).textTheme.bodyLarge, + ), + ); + } +} diff --git a/lib/programs_info_pages/sob_info.dart b/lib/programs_info_pages/sob_info.dart new file mode 100644 index 0000000..12f718d --- /dev/null +++ b/lib/programs_info_pages/sob_info.dart @@ -0,0 +1,221 @@ +import 'package:flutter/material.dart'; +import 'package:timeline_tile/timeline_tile.dart'; + +class SOBInfo extends StatelessWidget { + const SOBInfo({super.key}); + + @override + Widget build(BuildContext context) { + final List> events = [ + {'date': 'February 1, 2024', 'description': 'Student Application Period begins. Students can start applying to a track of their choice.'}, + {'date': 'February 19, 2024 at 23:59 UTC', 'description': 'Student Application Period ends. Application deadline for students to apply.'}, + {'date': 'February 16, 2024 - March 31, 2024', 'description': 'Learning Bootcamp. Screened students undergo an intensive bootcamp to learn about bitcoin.'}, + {'date': 'April 1, 2024', 'description': 'Project ideas for the internship program published on the website.'}, + {'date': 'April 1, 2024 - April 30, 2024', 'description': 'Proposal Round. Applicants submit their assignment solutions and project proposals for chosen project ideas.'}, + {'date': 'May 1, 2024 - May 7, 2024', 'description': 'Proposal Review Period. Mentors review and select project proposals.'}, + {'date': 'May 7, 2024', 'description': 'Accepted Students Announced. Accepted students are notified of their acceptance into the program.'}, + {'date': 'May 8, 2024 - May 15, 2024', 'description': 'Program Kick-Off and Onboarding. Accepted students are paired with mentors and start planning their projects and milestones.'}, + {'date': 'May 15, 2024 - August 15, 2024', 'description': 'Project Period. Students work on their Summer of Bitcoin projects.'}, + {'date': 'July 15, 2024 - July 20, 2024', 'description': 'Mid-term Evaluations. Mentors submit evaluations of their mentees. Passing students receive the first part of their stipend.'}, + {'date': 'August 19, 2024', 'description': 'Students Submit Projects. Final project report, including summaries and code submissions, due.'}, + {'date': 'August 19, 2024 - August 30, 2024', 'description': 'Final Evaluations. Mentors review student submissions to determine if projects are successfully completed.'}, + {'date': 'September 5, 2024', 'description': 'Results Announced. Students are notified of their pass/fail status. Passing students receive the final part of their stipend and a certificate of completion.'}, + {'date': 'Post Program Completion', 'description': 'Job Referrals. Exceptional students are offered opportunities for internships or full-time roles with bitcoin companies.'} + ]; + + + return Scaffold( + appBar: AppBar( + title: const Text('Project Information'), + ), + body: Padding( + padding: const EdgeInsets.all(10.0), + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Summer of Bitcoin', + style: Theme.of(context).textTheme.titleLarge, + ), + const SizedBox(height: 20), + _buildOutlinedBox( + context, + title: 'Overview', + content: 'A global, online summer internship program focused on introducing university students to bitcoin open-source development and design.', + ), + const SizedBox(height: 20), + _buildOutlinedBox( + context, + title: 'Eligibility : What are the eligibility requirements for students?', + content: + 'You must:\n' + '- Be a student enrolled in a university or high school program.\n' + '- Communicate effectively and clearly in English, with respect and courtesy.\n' + '- Have strong programming or design skills and experience with open-source development.\n' + '- Have experience with Git or be able to learn it quickly (applicable for developer track).\n\n' + 'Availability:\n' + '- Be available to work full-time during the summer.\n' + '- Ensure that during the 12 weeks of the summer internship, nothing takes precedence over your project and you have no major distractions.\n' + '- If you have another job, decide between it and Summer of Bitcoin; you should choose one.\n' + '- If you have significant extra commitments, it is unlikely you will be successful in the program.\n\n' + 'Connectivity:\n' + '- Have good Internet connectivity throughout the summer.\n' + '- Be able to stay in regular, close contact with mentors via usual open-source means (email, chat, Jitsi, etc.) for the duration of the summer. Geographic proximity to your mentor is not necessary.', + ), + + const SizedBox(height: 20), + Text( + 'Program Timeline', + style: Theme.of(context).textTheme.headlineSmall, + ), + const SizedBox(height: 10), + _buildTimeline(events), + const SizedBox(height: 20), + Text( + 'Prizes and Rewards', + style: Theme.of(context).textTheme.headlineSmall, + ), + const SizedBox(height: 10), + Column( + children: [ + _buildPrizeBox( + context, + 'Selected applicants get a ton of exciting swags, such as a bitcoin t-shirt, a bitcoin hardware wallet, a bitcoin book, cup, stickers and a cool bitcoin bag.', + ), + const SizedBox(height: 10), + _buildPrizeBox( + context, + 'By participating in Bitcoin, you will receive a certificate of completion that will add prestigious credentials to your resume. It will highlight your expertise and commitment to excellence in open-source development and design.', + ), + const SizedBox(height: 10), + _buildPrizeBox( + context, + 'Students who complete Summer of Bitcoin successfully get a handsome amount of 3000 dollars as a stipend.', + ), + const SizedBox(height: 10), + _buildPrizeBox( + context, + 'You will also be eligible for job referrals. Exceptional students are offered opportunities for internships or full-time roles with bitcoin companies.', + ), + ], + ), + ], + ), + ), + ), + ); + } + + Widget _buildOutlinedBox(BuildContext context, {required String title, required String content}) { + return Container( + padding: const EdgeInsets.all(10.0), + decoration: BoxDecoration( + border: Border.all(color: Colors.orange, width: 1.0), + borderRadius: BorderRadius.circular(8.0), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: Theme.of(context).textTheme.headlineSmall, + ), + const SizedBox(height: 10), + Text( + content, + style: Theme.of(context).textTheme.bodyLarge, + ), + ], + ), + ); + } + + Widget _buildTimeline(List> events) { + return Column( + children: events.asMap().entries.map((entry) { + int index = entry.key; + Map event = entry.value; + final bool isFirst = index == 0; + final bool isLast = index == events.length - 1; + final bool isLeft = index % 2 == 0; + + return TimelineTile( + axis: TimelineAxis.vertical, + alignment: TimelineAlign.center, + isFirst: isFirst, + isLast: isLast, + beforeLineStyle: const LineStyle( + color: Colors.orange, + thickness: 4, + ), + afterLineStyle: const LineStyle( + color: Colors.orange, + thickness: 4, + ), + indicatorStyle: IndicatorStyle( + indicator: Container( + decoration: const BoxDecoration( + color: Colors.orange, + shape: BoxShape.circle, + ), + child: const Icon( + Icons.event, + size: 15, + color: Colors.white, + ), + ), + ), + startChild: isLeft ? _buildEventChild(event) : null, + endChild: isLeft ? null : _buildEventChild(event), + ); + }).toList(), + ); + } + + Widget _buildEventChild(Map event) { + return Container( + width: 150, + margin: const EdgeInsets.all(10), + padding: const EdgeInsets.all(10), + decoration: BoxDecoration( + color: Colors.orange, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + event['date'], + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 16, + ), + ), + const SizedBox(height: 8), + Text( + event['description'], + style: const TextStyle( + fontSize: 14, + ), + ), + ], + ), + ); + } + + Widget _buildPrizeBox(BuildContext context, String description) { + return Container( + padding: const EdgeInsets.all(10.0), + decoration: BoxDecoration( + border: Border.all(color: Colors.orange, width: 1.0), + borderRadius: BorderRadius.circular(8), + ), + child: Text( + description, + textAlign: TextAlign.center, + style: Theme.of(context).textTheme.bodyLarge, + ), + ); + } +} diff --git a/lib/programs_info_pages/sokde_info.dart b/lib/programs_info_pages/sokde_info.dart new file mode 100644 index 0000000..41fc186 --- /dev/null +++ b/lib/programs_info_pages/sokde_info.dart @@ -0,0 +1,208 @@ +import 'package:flutter/material.dart'; +import 'package:timeline_tile/timeline_tile.dart'; + +class SOKDEInfo extends StatelessWidget { + const SOKDEInfo({super.key}); + + @override + Widget build(BuildContext context) { + final List> events = [ + {'date': '2023-12-15', 'description': 'START OF SEASON OF KDE 2024'}, + {'date': '2024-01-08', 'description': 'DEADLINE FOR THE CONTRIBUTORS APPLICATIONS'}, + {'date': '2024-01-15', 'description': 'PROJECTS ANNOUNCED'}, + {'date': '2024-01-17', 'description': 'START OF WORK'}, + {'date': '2024-03-31', 'description': 'END OF WORK'}, + {'date': '2024-04-07', 'description': 'RESULTS ANNOUNCED'}, + {'date': '2024-05-20', 'description': 'CERTIFICATES ISSUED'}, + {'date': 'After the end', 'description': 'MERCHANDISE AND SWAG SENT OUT BY COURIER'}, + ]; + + + + return Scaffold( + appBar: AppBar( + title: const Text('Project Information'), + ), + body: Padding( + padding: const EdgeInsets.all(10.0), + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Season of KDE', + style: Theme.of(context).textTheme.titleLarge, + ), + const SizedBox(height: 20), + _buildOutlinedBox( + context, + title: 'Overview', + content: 'Season of KDE is an outreach program hosted by the KDE community. Every year since 2013, KDE has been running Season of KDE (SoK) as a program similar to, but not quite the same as Google Summer of Code. SoK offers everyone an opportunity to participate in both code and non-code projects which benefit the KDE ecosystem.', + ), + const SizedBox(height: 20), + _buildOutlinedBox( + context, + title: 'Eligibility', + content: 'Is there any registration fees?\n' + 'No, there’s no registration fees. It is absolutely free for participants.\n\n' + 'Who all can participate?\n' + 'There is no restriction on who can participate.\n\n' + 'Any age limit for participation?\n' + 'No, there is no age limit for participation in Season of KDE. It is open for all.', + ), + + const SizedBox(height: 20), + Text( + 'Program Timeline', + style: Theme.of(context).textTheme.headlineSmall, + ), + const SizedBox(height: 10), + _buildTimeline(events), + const SizedBox(height: 20), + Text( + 'Prizes and Rewards', + style: Theme.of(context).textTheme.headlineSmall, + ), + const SizedBox(height: 10), + Center( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + children: [ + Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: _buildPrizeBox( + context, + 'Certificates to all the participants upon successful completion of the program', + ), + ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: _buildPrizeBox( + context, + 'Merchandise and swag sent out by courier to all the participants after the end of the program', + ), + ), + ], + ), + ), + ), + ], + ), + ), + ), + ); + } + + Widget _buildOutlinedBox(BuildContext context, {required String title, required String content}) { + return Container( + padding: const EdgeInsets.all(10.0), + decoration: BoxDecoration( + border: Border.all(color: Colors.orange, width: 1.0), + borderRadius: BorderRadius.circular(8.0), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: Theme.of(context).textTheme.headlineSmall, + ), + const SizedBox(height: 10), + Text( + content, + style: Theme.of(context).textTheme.bodyLarge, + ), + ], + ), + ); + } + + Widget _buildTimeline(List> events) { + return Column( + children: events.asMap().entries.map((entry) { + int index = entry.key; + Map event = entry.value; + final bool isFirst = index == 0; + final bool isLast = index == events.length - 1; + final bool isLeft = index % 2 == 0; + + return TimelineTile( + axis: TimelineAxis.vertical, + alignment: TimelineAlign.center, + isFirst: isFirst, + isLast: isLast, + beforeLineStyle: const LineStyle( + color: Colors.orange, + thickness: 4, + ), + afterLineStyle: const LineStyle( + color: Colors.orange, + thickness: 4, + ), + indicatorStyle: IndicatorStyle( + indicator: Container( + decoration: const BoxDecoration( + color: Colors.orange, + shape: BoxShape.circle, + ), + child: const Icon( + Icons.event, + size: 15, + color: Colors.white, + ), + ), + ), + startChild: isLeft ? _buildEventChild(event) : null, + endChild: isLeft ? null : _buildEventChild(event), + ); + }).toList(), + ); + } + + Widget _buildEventChild(Map event) { + return Container( + width: 150, + margin: const EdgeInsets.all(10), + padding: const EdgeInsets.all(10), + decoration: BoxDecoration( + color: Colors.orange, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + event['date'], + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 16, + ), + ), + const SizedBox(height: 8), + Text( + event['description'], + style: const TextStyle( + fontSize: 14, + ), + ), + ], + ), + ); + } + + Widget _buildPrizeBox(BuildContext context, String description) { + return Container( + padding: const EdgeInsets.all(10.0), + decoration: BoxDecoration( + border: Border.all(color: Colors.orange, width: 1.0), + borderRadius: BorderRadius.circular(8), + ), + child: Text( + description, + textAlign: TextAlign.center, + style: Theme.of(context).textTheme.bodyLarge, + ), + ); + } +} diff --git a/lib/programs_info_pages/swoc_info.dart b/lib/programs_info_pages/swoc_info.dart new file mode 100644 index 0000000..9d2a12e --- /dev/null +++ b/lib/programs_info_pages/swoc_info.dart @@ -0,0 +1,216 @@ +import 'package:flutter/material.dart'; +import 'package:timeline_tile/timeline_tile.dart'; + +class SWOCInfo extends StatelessWidget { + const SWOCInfo({super.key}); + + @override + Widget build(BuildContext context) { + final List> events = [ + {'date': '15 Aug 2023', 'description': 'Participant Registration starts'}, + {'date': '20 Aug 2023', 'description': 'Project and Mentor Registration Starts'}, + {'date': '15 Dec 2023', 'description': 'Project Registrations ends'}, + {'date': '20 Dec 2023', 'description': 'Participants and mentors registrations ends'}, + {'date': '22 Dec 2023', 'description': 'Acceptance Mails Sent'}, + {'date': '22 Dec 2023', 'description': 'Projects Announcement'}, + {'date': '1 Jan 2024', 'description': 'SWoC Begins'}, + {'date': '28 Feb 2024', 'description': 'SWoC Ends'}, + {'date': '15 Mar 2024', 'description': 'Results Announcement'}, + ]; + + return Scaffold( + appBar: AppBar( + title: const Text('Project Information'), + ), + body: Padding( + padding: const EdgeInsets.all(10.0), + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Social Winter Of Code', + style: Theme.of(context).textTheme.titleLarge, + ), + const SizedBox(height: 20), + _buildOutlinedBox( + context, + title: 'Overview', + content: 'Social Winter Of Code is a 2-month long open source program by Social India, with the aim to introduce more and more people to the world of Open Source. ' + 'In this program, all the selected participants will get a chance to work on various exciting projects under the guidance of experienced mentors.' + '\n\nParticipants can select the project based on their interest and tech stack, and can communicate with mentors and project admins to know the project better during the Community Bonding Period.', + ), + const SizedBox(height: 20), + _buildOutlinedBox( + context, + title: 'Eligibility', + content: 'Is there any registration fees?\n' + 'No, there’s no registration fees. It is absolutely free for participants.\n\n' + 'Who all can participate?\n' + 'No matter if you are a beginner or an expert, SWOC is open for everyone who has a zeal to learn new things and achieve heights.\n\n' + 'Any age limit for participation?\n' + 'No, it is open for all.', + ), + const SizedBox(height: 20), + Text( + 'Program Timeline', + style: Theme.of(context).textTheme.headlineSmall, + ), + const SizedBox(height: 10), + _buildTimeline(events), + const SizedBox(height: 20), + Text( + 'Prizes and Rewards', + style: Theme.of(context).textTheme.headlineSmall, + ), + const SizedBox(height: 10), + SizedBox( + child: GridView.count( + shrinkWrap: true, + crossAxisCount: 2, + children: [ + _buildPrizeBox( + context, + 'assets/github_swag.png', + 'SWOC, GitHub swag kits\nTop 10 Contributors', + ), + _buildPrizeBox( + context, + 'assets/xyz_domain.png', + '.xyz domains\nTop 40', + ), + _buildPrizeBox( + context, + 'assets/participation_certificate.png', + 'Participation Certificate\nFor all', + ), + _buildPrizeBox( + context, + 'assets/coding_ninja_swag.png', + 'Swags from Coding Ninja\nTop 1', + ), + ], + ), + ), + ], + ), + ), + ), + ); + } + + Widget _buildOutlinedBox(BuildContext context, {required String title, required String content}) { + return Container( + padding: const EdgeInsets.all(10.0), + decoration: BoxDecoration( + border: Border.all(color: Colors.orange, width: 1.0), + borderRadius: BorderRadius.circular(8.0), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: Theme.of(context).textTheme.headlineSmall, + ), + const SizedBox(height: 10), + Text( + content, + style: Theme.of(context).textTheme.bodyLarge, + ), + ], + ), + ); + } + + Widget _buildTimeline(List> events) { + return Column( + children: events.asMap().entries.map((entry) { + int index = entry.key; + Map event = entry.value; + final bool isFirst = index == 0; + final bool isLast = index == events.length - 1; + final bool isLeft = index % 2 == 0; + + return TimelineTile( + axis: TimelineAxis.vertical, + alignment: TimelineAlign.center, + isFirst: isFirst, + isLast: isLast, + beforeLineStyle: const LineStyle( + color: Colors.orange, + thickness: 4, + ), + afterLineStyle: const LineStyle( + color: Colors.orange, + thickness: 4, + ), + indicatorStyle: IndicatorStyle( + indicator: Container( + decoration: const BoxDecoration( + color: Colors.orange, + shape: BoxShape.circle, + ), + child: const Icon( + Icons.event, + size: 15, + color: Colors.white, + ), + ), + ), + startChild: isLeft ? _buildEventChild(event) : null, + endChild: isLeft ? null : _buildEventChild(event), + ); + }).toList(), + ); + } + + Widget _buildEventChild(Map event) { + return Container( + width: 150, + margin: const EdgeInsets.all(25), + padding: const EdgeInsets.all(25), + decoration: BoxDecoration( + color: Colors.orange, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + event['date'], + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 16, + ), + ), + const SizedBox(height: 8), + Text( + event['description'], + style: const TextStyle( + fontSize: 14, + ), + ), + ], + ), + ); + } + + Widget _buildPrizeBox(BuildContext context, String imagePath, String description) { + return Column( + children: [ + CircleAvatar( + radius: 40, + backgroundImage: AssetImage(imagePath), + backgroundColor: Colors.white, + ), + const SizedBox(height: 10), + Text( + description, + textAlign: TextAlign.center, + style: Theme.of(context).textTheme.bodyLarge, + ), + ], + ); + } +} diff --git a/lib/widgets/osoc_widget.dart b/lib/widgets/osoc_widget.dart new file mode 100644 index 0000000..9e53aca --- /dev/null +++ b/lib/widgets/osoc_widget.dart @@ -0,0 +1,56 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:opso/modals/osoc_modal.dart'; +import 'package:url_launcher/url_launcher.dart'; + +class OsocWidget extends StatelessWidget { + final OsocModal modal; + final double height; + final double width; + const OsocWidget( + {super.key, required this.modal, this.height = 100, this.width = 100}); + + @override + Widget build(BuildContext context) { + final isDarkMode = Theme.of(context).brightness == Brightness.dark; + final textColor = isDarkMode ? Colors.white : Colors.black; + final cardColor = isDarkMode ? Colors.grey.shade800 : Colors.white; + return GestureDetector( + onTap: () => launchUrl( + Uri.parse(modal.project_url), + ), + child: Container( + constraints: BoxConstraints( + minHeight: height, + ), + padding: const EdgeInsets.all(10), + width: width, + decoration: BoxDecoration( + color: cardColor, + borderRadius: BorderRadius.circular(20), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SvgPicture.network( + modal.image_url, + height: height * 0.5, + ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: Text( + modal.name, + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 20, + ), + textAlign: TextAlign.center, + ), + ), + Text(modal.description), + ], + ), + ), + ); + } +} diff --git a/lib/widgets/small_year_button.dart b/lib/widgets/small_year_button.dart new file mode 100644 index 0000000..19e0587 --- /dev/null +++ b/lib/widgets/small_year_button.dart @@ -0,0 +1,50 @@ +import 'package:flutter/material.dart'; + +class YearButton extends StatelessWidget { + final String year; + final Function()? onTap; + final Color backgroundColor; + final double fontSize; + final Color fontColor; + final bool isEnabled; + final Color selectedFontColor; + + const YearButton({ + Key? key, + required this.year, + required this.isEnabled, + this.onTap, + this.backgroundColor = Colors.orange, + this.fontSize = 20, + this.fontColor = Colors.white, + this.selectedFontColor = Colors.orange, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return ElevatedButton( + onPressed: onTap, + style: ElevatedButton.styleFrom( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + side: const BorderSide( + color: Color.fromRGBO(255, 183, 77, 1), + ), + ), + backgroundColor: backgroundColor, + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), + ), + child: FittedBox( + fit: BoxFit.scaleDown, + child: Text( + year, + style: TextStyle( + fontSize: fontSize, + color: isEnabled ? selectedFontColor : fontColor, + fontWeight: FontWeight.bold, + ), + ), + ), + ); + } +} diff --git a/lib/widgets/sokde_project_widget.dart b/lib/widgets/sokde_project_widget.dart new file mode 100644 index 0000000..305f8f6 --- /dev/null +++ b/lib/widgets/sokde_project_widget.dart @@ -0,0 +1,72 @@ +import 'package:flutter/material.dart'; +import 'package:opso/modals/sokde_project_modal.dart'; +import 'package:url_launcher/url_launcher.dart'; + +class SokdeProjectWidget extends StatelessWidget { + final SokdeProjectModal modal; + final double height; + final double width; + final int index; + + const SokdeProjectWidget({ + super.key, + required this.modal, + required this.index, + this.height = 100, + this.width = 100, + }); + + @override + Widget build(BuildContext context) { + bool isDarkMode = Theme.of(context).brightness == Brightness.dark; + return GestureDetector( + onTap: () async { + Uri uri = Uri.parse(modal.wiki); + if (await canLaunch(uri.toString())) { + await launch(uri.toString()); + } else { + throw 'Could not launch $uri'; + } + }, + child: Container( + width: width, + constraints: BoxConstraints(minHeight: height), + decoration: BoxDecoration( + border: Border.all( + color: isDarkMode ? Colors.orange.shade100 : Colors.orange.shade300, + width: 1, + ), + borderRadius: BorderRadius.circular(20), + ), + child: Padding( + padding: const EdgeInsets.all(15.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "$index. ${modal.name}", + style: const TextStyle( + color: Colors.orange, + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + Padding( + padding: const EdgeInsets.only(top: 10.0), + child: Text("Mentors: ${modal.mentors.join(', ')}"), + ), + Padding( + padding: const EdgeInsets.only(top: 5.0), + child: Text("Mentees: ${modal.mentees.join(', ')}"), + ), + Padding( + padding: const EdgeInsets.only(top: 20.0), + child: Text("Year: ${modal.year}"), + ), + ], + ), + ), + ), + ); + } +} diff --git a/pubspec.lock b/pubspec.lock index 5c109ab..dc98038 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -268,26 +268,26 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" + sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a" url: "https://pub.dev" source: hosted - version: "10.0.0" + version: "10.0.4" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 + sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.3" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.1" lints: dependency: transitive description: @@ -316,10 +316,10 @@ packages: dependency: transitive description: name: meta - sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 + sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.12.0" multi_select_flutter: dependency: "direct main" description: @@ -497,10 +497,10 @@ packages: dependency: transitive description: name: test_api - sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" + sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" url: "https://pub.dev" source: hosted - version: "0.6.1" + version: "0.7.0" timeline_tile: dependency: "direct main" description: @@ -617,10 +617,10 @@ packages: dependency: transitive description: name: vm_service - sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 + sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" url: "https://pub.dev" source: hosted - version: "13.0.0" + version: "14.2.1" web: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 935277f..5baa0e2 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -80,6 +80,7 @@ flutter: # - assets\outreachy.png # - assets\swoc_logo.png # - assets\Google_season_of_docs.png + # - assets\sokde.png # # - images/a_dot_ham.jpeg assets: - assets/ @@ -89,6 +90,14 @@ flutter: - assets/projects/swoc/ - assets/projects/linux_foundation/ - assets/splash screen.png + - assets/github_swag.png + - assets/sokde.png + - assets/xyz_domain.png + - assets/participation_certificate.png + - assets/coding_ninja_swag.png + - assets/projects/osoc/ + - assets/projects/sokde/ + # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/assets-and-images/#resolution-aware # For details regarding adding assets from package dependencies, see