diff --git a/Widgets/VolunteerTracker/Assets/screenshot-volunteertracker.png b/Widgets/VolunteerTracker/Assets/screenshot-volunteertracker.png new file mode 100644 index 0000000..58fad3f Binary files /dev/null and b/Widgets/VolunteerTracker/Assets/screenshot-volunteertracker.png differ diff --git a/Widgets/VolunteerTracker/README.md b/Widgets/VolunteerTracker/README.md new file mode 100644 index 0000000..52bc594 --- /dev/null +++ b/Widgets/VolunteerTracker/README.md @@ -0,0 +1,31 @@ +# Volunteer Tracker Widget + +The Volunteer Tracker is a Domino’s Pizza Tracker–inspired widget that helps volunteers see exactly where they are in the application process. Just like watching your pizza go from “Order Placed” to “Out for Delivery,” this tracker moves you from “Application Received” to “Ready to Serve!”—minus the melted cheese (unless you’re volunteering in the kitchen 🍕). + +## Features + +- **Domino’s-Style Progress Bar**: Big, bold, and colorful stages that light up as you complete each requirement. +- **Stages Include**: + 1. **Received** – Your application is in! + 2. **Leader Review** – Waiting for approval from your leader. + 3. **Background Check** – Show if a background check is required. + 4. **Additional Requirements** – Tracks milestones, certifications, and forms. + 5. **Ready to Serve!** – All steps complete and you’re good to go. +- **Helpful Links**: Direct links to complete background checks or forms if they’re still pending. +- **Contact Info**: Displays the opportunity leader’s name and email for quick help. +- **No Auth Required**: Just add ?response=[Response_ID]&cid=[Contact_GUID] to the URL this widget is on to load the tracker. + +## Configuration + +- Modify the stored procedure parameters to reflect your church's setup: + - **@BGCWebUrl** - Public web address for completing background checks. The Background_Check_GUID will be appended. + - **@FormWebUrl** - Public web location of a Custom Form widget. The Form_GUID will be appended. + - **@CheckTypeID** - The default/fallback Background_Check_Type_ID for your church. + - **@EnforceVolunteerGroup** - If set to 1, then the widget will _only_ work with Groups with a Type that is set as a Volunteer Group. +- Create any "Requirement" records for the Group Role associated with the Opportunity, if needed. This widget will show all distinct requirements associated with the Group Role. +- If no Background Check is set in a requirement record, but the Group Role requires a Background Check, then the default/fallback @CheckTypeID will be used. +- The "Leader Review" step utilizes the "Response Result" field on the Response record. Blank/Null will leave it in the "Pending" state, "Not Placed" will change the tracker to the "closed" state, and any other "Response Result" will advance the tracker to the next stage. + +## Screenshots + + \ No newline at end of file diff --git a/Widgets/VolunteerTracker/StoredProc/StoredProc.md b/Widgets/VolunteerTracker/StoredProc/StoredProc.md new file mode 100644 index 0000000..ed9613d --- /dev/null +++ b/Widgets/VolunteerTracker/StoredProc/StoredProc.md @@ -0,0 +1,17 @@ +# Stored Procedure Definition + +Use this folder to include any sql scripts designed to install Stored Procedures required for the Csutom Widget to work. Please follow the pattern of including a fully installable script including required MinistryPlatform metadata. Examplesa are included to aid in quickly developing installable Stored Procedure scripts + +## Installation Notes + +All examples in this repository will install the stored procedure, then check API_Procudures for the relevant metadata that defines the stored procedure. Additionally, install scripts will give the Administrators security role access to the script. + +## Standard Parameters + +The Custom Widget API will attempt to pass @UserName when the website user is logged into widgets. It is highly recommend that you include the @UserName parameter in all Custom Widget Stored Procedures. If @UserName is not required, you should default this parameter to null. When NOT NULL, the absense of this parameter will cause the stored procedure to fail. + +Example: + +``` +@UserName nvarchar(75) = null +``` diff --git a/Widgets/VolunteerTracker/StoredProc/api_custom_VolunteerTrackerWidget_JSON.sql b/Widgets/VolunteerTracker/StoredProc/api_custom_VolunteerTrackerWidget_JSON.sql new file mode 100644 index 0000000..108ff62 --- /dev/null +++ b/Widgets/VolunteerTracker/StoredProc/api_custom_VolunteerTrackerWidget_JSON.sql @@ -0,0 +1,263 @@ +DROP PROCEDURE IF EXISTS [dbo].[api_custom_VolunteerTrackerWidget_JSON] +GO + +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER ON +GO + +-- ============================================= +-- api_custom_VolunteerTrackerWidget_JSON +-- ============================================= +-- Description: Returns the status of requirements for a response to a volunteer opportunity. +-- Created at MP Dev Lab 2025 at Perimeter Church in Atlanta, Georgia. +-- Last Modified: 8/22/2025 +-- Stephan Swinford +-- ============================================= + +CREATE PROCEDURE [dbo].[api_custom_VolunteerTrackerWidget_JSON] + @DomainID INT, + @Username NVARCHAR(75) = NULL, + @BGCWebUrl NVARCHAR(255) = 'https://yourchurch.ministryplatform.com/portal/backgroundcheck.aspx?background=', + @FormWebUrl NVARCHAR(255) = 'https://www.yourchurch.org/form?id=', + @CheckTypeID INT = 1, --Default Background Check Type ID + @EnforceVolunteerGroup INT = 0, --Enforce whether associated opportunity group must be a 'volunteer group' or not + @ContactGUID NVARCHAR(75), + @ResponseID INT + +AS +BEGIN + SET NOCOUNT ON; + + -- Verify that the Contact_GUID associated with the Reponse matches the provided Contact GUID + IF NOT EXISTS ( + SELECT 1 + FROM Contacts C + JOIN Participants P ON P.Contact_ID = C.Contact_ID + JOIN Responses R ON R.Participant_ID = P.Participant_ID + WHERE R.Response_ID = @ResponseID + AND C.Contact_GUID = @ContactGUID + ) + BEGIN + SELECT [JsonResult] = (SELECT 'Invalid data in URL. Please check your URL and try again.' AS ErrorMessage FOR JSON PATH, WITHOUT_ARRAY_WRAPPER); + RETURN; + END + + SELECT [JsonResult] = + ( + SELECT + + /* 1) Volunteer Information -> object (embedded without escaping) */ + JSON_QUERY( + COALESCE( + ( + SELECT TOP 1 + C.Nickname, + C.Last_Name, + C2.Nickname AS Opportunity_Contact_Nickname, + C2.Last_Name AS Opportunity_Contact_Last_Name, + C2.Email_Address AS Opportunity_Contact_Email, + O.Opportunity_Title, + R.Response_Date, + CASE WHEN R.Closed = 1 AND ISNULL(RR.Response_Result_ID, 2) = 2 THEN 1 ELSE 0 END AS Closed, + ISNULL(RR.Response_Result, 'Pending') AS [Leader_Review], + CASE WHEN @EnforceVolunteerGroup = 0 THEN 1 ELSE GT.Volunteer_Group END AS [Is_Volunteer_Group], + R.Response_ID, + C.Contact_GUID + FROM Contacts C + JOIN Responses R ON R.Response_ID = @ResponseID + JOIN Opportunities O ON O.Opportunity_ID = R.Opportunity_ID + JOIN Contacts C2 ON C2.Contact_ID = O.Contact_Person + LEFT JOIN Groups G ON G.Group_ID = O.Add_to_Group + LEFT JOIN Group_Types GT ON GT.Group_Type_ID = G.Group_Type_ID + LEFT JOIN Response_Results RR ON RR.Response_Result_ID = R.Response_Result_ID + WHERE R.Response_ID = @ResponseID + AND C.Contact_GUID = @ContactGUID + ORDER BY C.Contact_ID DESC + FOR JSON PATH, WITHOUT_ARRAY_WRAPPER + ), + N'{}' -- fallback to an empty object if no match + ) + ) AS volunteer_information, + + /* 2) Background Check Requirements -> array */ + ( + SELECT DISTINCT + BCT.Background_Check_Type AS Background_Check_Type, + CASE WHEN (EXISTS + ( + SELECT 1 + FROM Background_Checks BC + WHERE BC.Background_Check_Type_ID = BCT.Background_Check_Type_ID + AND BC.Contact_ID = P.Contact_ID + AND BC.All_Clear = 1 + AND BC.Background_Check_Expires > GETDATE() + ) + OR (PR.Background_Check_Type_ID IS NULL AND GR.Background_Check_Required=1 AND EXISTS + ( + SELECT 1 + FROM Background_Checks BC + WHERE BC.Contact_ID = P.Contact_ID + AND BC.All_Clear = 1 + AND BC.Background_Check_Expires > GETDATE() + )) + ) + THEN 'Completed' + WHEN (EXISTS + ( + SELECT 1 + FROM Background_Checks BC + WHERE BC.Background_Check_Type_ID = BCT.Background_Check_Type_ID + AND BC.Contact_ID = P.Contact_ID + AND BC.Background_Check_Started >= GetDate()-60 + AND BC.Background_Check_Submitted IS NOT NULL + ) + OR (PR.Background_Check_Type_ID IS NULL AND GR.Background_Check_Required=1 AND EXISTS + ( + SELECT 1 + FROM Background_Checks BC + WHERE BC.Contact_ID = P.Contact_ID + AND BC.Background_Check_Started >= GetDate()-60 + AND BC.Background_Check_Submitted IS NOT NULL + )) + ) THEN 'Submitted' + ELSE 'Needed' END AS Background_Check_Status, + ISNULL(( + SELECT TOP 1 + CONCAT(@BGCWebUrl, BC.Background_Check_GUID) + FROM Background_Checks BC + WHERE BC.Background_Check_Type_ID = BCT.Background_Check_Type_ID + AND BC.Contact_ID = P.Contact_ID + AND BC.Background_Check_Started >= GetDate()-60 + AND BC.Background_Check_Submitted IS NULL + ORDER BY BC.Background_Check_Started DESC + ), '') AS Background_Check_URL + FROM Participation_Requirements PR + INNER JOIN Group_Roles GR ON GR.Group_Role_ID = PR.Group_Role_ID + INNER JOIN Opportunities O ON O.Group_Role_ID = GR.Group_Role_ID + INNER JOIN Responses R ON R.Opportunity_ID = O.Opportunity_ID + LEFT JOIN Background_Check_Types BCT ON BCT.Background_Check_Type_ID = ISNULL(PR.Background_Check_Type_ID, @CheckTypeID) + INNER JOIN Participants P ON P.Participant_ID = R.Participant_ID + INNER JOIN Contacts C ON C.Contact_ID = P.Contact_ID + WHERE R.Response_ID = @ResponseID + AND C.Contact_GUID = @ContactGUID + FOR JSON PATH + ) AS background_checks, + + /* 3) Milestone Requirements -> array */ + ( + SELECT DISTINCT + M.Milestone_Title, + CASE WHEN EXISTS + ( + SELECT 1 + FROM Participant_Milestones PM + WHERE PM.Milestone_ID = M.Milestone_ID + AND PM.Participant_ID = P.Participant_ID + AND (DATEADD(MONTH, ISNULL(M.Expires_in_Months, 0), PM.Date_Accomplished) > GETDATE() + OR M.Expires_in_Months IS NULL) + ) + THEN 'Completed' ELSE 'Needed' END AS Milestone_Status + FROM Participation_Requirements PR + INNER JOIN Group_Roles GR ON GR.Group_Role_ID = PR.Group_Role_ID + INNER JOIN Opportunities O ON O.Group_Role_ID = GR.Group_Role_ID + INNER JOIN Responses R ON R.Opportunity_ID = O.Opportunity_ID + INNER JOIN Milestones M ON M.Milestone_ID = PR.Milestone_ID + INNER JOIN Participants P ON P.Participant_ID = R.Participant_ID + INNER JOIN Contacts C ON C.Contact_ID = P.Contact_ID + WHERE R.Response_ID = @ResponseID + AND C.Contact_GUID = @ContactGUID + FOR JSON PATH + ) AS milestones, + + /* 4) Certification Requirements -> array */ + ( + SELECT DISTINCT + CT.Certification_Type, + CASE WHEN EXISTS + ( + SELECT 1 + FROM Participant_Certifications PC + WHERE PC.Certification_Type_ID = CT.Certification_Type_ID + AND PC.Participant_ID = P.Participant_ID + AND ISNULL(PC.Certification_Expires, GETDATE()) > GETDATE() + ) + THEN 'Completed' ELSE 'Needed' END AS Certification_Status + FROM Participation_Requirements PR + INNER JOIN Group_Roles GR ON GR.Group_Role_ID = PR.Group_Role_ID + INNER JOIN Opportunities O ON O.Group_Role_ID = GR.Group_Role_ID + INNER JOIN Responses R ON R.Opportunity_ID = O.Opportunity_ID + INNER JOIN Certification_Types CT ON CT.Certification_Type_ID = PR.Certification_Type_ID + INNER JOIN Participants P ON P.Participant_ID = R.Participant_ID + INNER JOIN Contacts C ON C.Contact_ID = P.Contact_ID + WHERE R.Response_ID = @ResponseID + AND C.Contact_GUID = @ContactGUID + FOR JSON PATH + ) AS certifications, + + /* 5) Form Requirements -> array */ + ( + SELECT DISTINCT + F.Form_Title, + CONCAT(@FormWebUrl, F.Form_GUID) AS Form_URL, + CASE WHEN EXISTS + ( + SELECT 1 + FROM Form_Responses FR + WHERE FR.Form_ID = F.Form_ID + AND FR.Contact_ID = P.Contact_ID + AND DATEADD(MONTH, ISNULL(F.Months_Till_Expires, 1), FR.Response_Date) > GETDATE() + ) + THEN 'Completed' ELSE 'Needed' END AS Form_Status + FROM Participation_Requirements PR + INNER JOIN Group_Roles GR ON GR.Group_Role_ID = PR.Group_Role_ID + INNER JOIN Opportunities O ON O.Group_Role_ID = GR.Group_Role_ID + INNER JOIN Responses R ON R.Opportunity_ID = O.Opportunity_ID + INNER JOIN Forms F ON F.Form_ID = PR.Custom_Form_ID + INNER JOIN Participants P ON P.Participant_ID = R.Participant_ID + INNER JOIN Contacts C ON C.Contact_ID = P.Contact_ID + WHERE R.Response_ID = @ResponseID + AND C.Contact_GUID = @ContactGUID + FOR JSON PATH + ) AS forms + + FOR JSON PATH, WITHOUT_ARRAY_WRAPPER + ); +END +GO + + +-- ============================================= +-- SP MetaData Install +-- ============================================= +DECLARE @spName NVARCHAR(128) = 'api_custom_VolunteerTrackerWidget_JSON' +DECLARE @spDescription NVARCHAR(500) = 'Returns the status of requirements for a response to a volunteer opportunity.' + +IF NOT EXISTS ( + SELECT API_Procedure_ID FROM dp_API_Procedures WHERE Procedure_Name = @spName +) +BEGIN + INSERT INTO dp_API_Procedures (Procedure_Name, Description) + VALUES (@spName, @spDescription) +END + +-- Grant to Administrators Role +DECLARE @AdminRoleID INT = ( + SELECT Role_ID FROM dp_Roles WHERE Role_Name = 'Administrators' +) + +IF NOT EXISTS ( + SELECT * + FROM dp_Role_API_Procedures RP + INNER JOIN dp_API_Procedures AP ON AP.API_Procedure_ID = RP.API_Procedure_ID + WHERE AP.Procedure_Name = @spName AND RP.Role_ID = @AdminRoleID +) +BEGIN + INSERT INTO dp_Role_API_Procedures (Domain_ID, API_Procedure_ID, Role_ID) + VALUES ( + 1, + (SELECT API_Procedure_ID FROM dp_API_Procedures WHERE Procedure_Name = @spName), + @AdminRoleID + ) +END +GO diff --git a/Widgets/VolunteerTracker/Template/VolunteerTracker.html b/Widgets/VolunteerTracker/Template/VolunteerTracker.html new file mode 100644 index 0000000..95d7a19 --- /dev/null +++ b/Widgets/VolunteerTracker/Template/VolunteerTracker.html @@ -0,0 +1,676 @@ +{%- comment -%} +Domino’s-style volunteer tracker with large, boldly colored segments that "light up". +Top-level inputs expected: + - volunteer_information (object) + - background_checks (array) + - milestones (array) + - certifications (array) + - forms (array) + - leader_review (string: "completed" or "pending") + - widgetId (optional), userAuthenticated (optional) — not displayed +Stages (left → right): + 1) Received (always complete) + 2) Leader Review (from `leader_review`) + 3) Background Check (all background_checks complete OR none => complete) + 4) Additional Requirements (all milestones+certifications+forms complete OR none => complete) + 5) Ready to Serve! (when 2–4 complete) +{%- endcomment -%} + +{% assign vi = volunteer_information %} + +{% comment %} Guard: Check if there is a URL error and only render tracker for volunteer-type groups {% endcomment %} +{% assign vol_raw = vi["Is_Volunteer_Group"] %} +{% assign vol_txt = vol_raw | downcase | strip %} +{% assign is_volunteer = false %} +{% if vol_raw == 1 or vol_txt == '1' or vol_raw == true or vol_txt == 'true' %} + {% assign is_volunteer = true %} +{% endif %} + +{% if ErrorMessage %} +
+
+

This URL contains invalid data. Please check your link and try again.

+
+
+ +{% elsif is_volunteer == false %} +
+
+

{{ vi["Opportunity_Title"] | default: "This opportunity" }} is not configured as a volunteer team. Tracker not available.

+
+
+ +{% else %} + +{%- comment -%} ✅ Robust list of "done" words (comma-separated, trimmed later) {%- endcomment -%} +{%- assign YES_WORDS = "completed,approved,passed,done,ok,submitted,yes,active,cleared,verified" | split: "," -%} + +{%- comment -%} --- Leader Review --- {%- endcomment -%} +{% assign leader_review_status = vi["Leader_Review"] | default: "Pending" | downcase | strip %} +{% assign leader_review_done = false %} +{% if leader_review_status != "pending" and leader_review_status != "not placed" %} + {% assign leader_review_done = true %} +{% endif %} + +{%- comment -%} --- Background Checks completion --- {%- endcomment -%} +{% assign bc_total = 0 %} +{% assign bc_complete = 0 %} +{% if background_checks %} + {% assign bc_total = background_checks.size %} + {% for bc in background_checks %} + {% assign s = bc["Background_Check_Status"] | downcase | strip %} + {% assign done_flag = false %} + {% for w in YES_WORDS %} + {% assign w_t = w | downcase | strip %} + {% if w_t != "" and s contains w_t %} + {% assign done_flag = true %} + {% endif %} + {% endfor %} + {% if done_flag %} + {% assign bc_complete = bc_complete | plus: 1 %} + {% endif %} + {% endfor %} +{% endif %} +{% assign background_done = false %} +{% if bc_total == 0 or bc_total == bc_complete %} + {% assign background_done = true %} +{% endif %} + +{%- comment -%} --- Additional Requirements (milestones + certifications + forms) --- {%- endcomment -%} +{% assign req_total = 0 %} +{% assign req_complete = 0 %} + +{% if milestones %} + {% assign req_total = req_total | plus: milestones.size %} + {% for m in milestones %} + {% assign s = m["Milestone_Status"] | downcase | strip %} + {% assign done_flag = false %} + {% for w in YES_WORDS %} + {% assign w_t = w | downcase | strip %} + {% if w_t != "" and s contains w_t %} + {% assign done_flag = true %} + {% endif %} + {% endfor %} + {% if done_flag %} + {% assign req_complete = req_complete | plus: 1 %} + {% endif %} + {% endfor %} +{% endif %} + +{% if certifications %} + {% assign req_total = req_total | plus: certifications.size %} + {% for c in certifications %} + {% assign s = c["Certification_Status"] | downcase | strip %} + {% assign done_flag = false %} + {% for w in YES_WORDS %} + {% assign w_t = w | downcase | strip %} + {% if w_t != "" and s contains w_t %} + {% assign done_flag = true %} + {% endif %} + {% endfor %} + {% if done_flag %} + {% assign req_complete = req_complete | plus: 1 %} + {% endif %} + {% endfor %} +{% endif %} + +{% if forms %} + {% assign req_total = req_total | plus: forms.size %} + {% for f in forms %} + {% assign s = f["Form_Status"] | downcase | strip %} + {% assign done_flag = false %} + {% for w in YES_WORDS %} + {% assign w_t = w | downcase | strip %} + {% if w_t != "" and s contains w_t %} + {% assign done_flag = true %} + {% endif %} + {% endfor %} + {% if done_flag %} + {% assign req_complete = req_complete | plus: 1 %} + {% endif %} + {% endfor %} +{% endif %} + +{% assign addl_done = false %} +{% if req_total == 0 or req_total == req_complete %} + {% assign addl_done = true %} +{% endif %} + +{%- comment -%} --- Determine if any background check requirements exist --- {%- endcomment -%} +{% assign any_bc = false %} +{% if background_checks and background_checks.size > 0 %} + {% assign any_bc = true %} +{% endif %} + +{%- comment -%} --- Determine if any additional requirements exist --- {%- endcomment -%} +{% assign any_addl = false %} +{% if milestones and milestones.size > 0 %}{% assign any_addl = true %}{% endif %} +{% if certifications and certifications.size > 0 %}{% assign any_addl = true %}{% endif %} +{% if forms and forms.size > 0 %}{% assign any_addl = true %}{% endif %} + +{%- comment -%} --- Ready to Serve (final) --- {%- endcomment -%} +{% assign ready_done = false %} +{% if leader_review_done and background_done and addl_done %} + {% assign ready_done = true %} +{% endif %} + +{%- comment -%} Determine current (first not done; Received is always done) {%- endcomment -%} +{% assign current_idx = 5 %} +{% assign s1_done = true %} +{% assign s2_done = leader_review_done %} +{% assign s3_done = background_done %} +{% assign s4_done = addl_done %} +{% assign s5_done = ready_done %} +{% if s2_done == false %} + {% assign current_idx = 2 %} +{% elsif s3_done == false %} + {% assign current_idx = 3 %} +{% elsif s4_done == false %} + {% assign current_idx = 4 %} +{% elsif s5_done == false %} + {% assign current_idx = 5 %} +{% endif %} + +
+
+

+ {{ vi["Nickname"] | default: "—" }} {{ vi["Last_Name"] | default: "" }} +

+
+ Volunteer Application for {{ vi["Opportunity_Title"] | default: "—" }} + + {% if vi["Response_Date"] %} + Submitted on {{ vi["Response_Date"] | date: "%b %-d, %Y %I:%M %p" }} + {% else %}—{% endif %} + {% assign is_closed = vi["Closed"] %} + {% if ready_done == true %} + Completed + {% elsif leader_review_status == "not placed" %} + Closed + {% else %} + Open + {% endif %} +
+
+ + +
+
+ {% assign stages = "Received +Leader Review" | split:"\n" %} +{% if any_bc %} + {% assign stages = stages | push: "Background Check" %} +{% endif %} +{% if any_addl %} + {% assign stages = stages | push: "Additional Requirements" %} +{% endif %} +{% assign stages = stages | push: "Ready to Serve!" %} + + + {% for s in stages %} + {% assign idx = forloop.index %} + + {%- comment -%} Determine raw done flags for each stage {%- endcomment -%} + {% assign done = false %} + {% if idx == 1 and s1_done %}{% assign done = true %}{% endif %} + {% if idx == 2 and s2_done %}{% assign done = true %}{% endif %} + {% if idx == 3 and s3_done %}{% assign done = true %}{% endif %} + {% if idx == 4 and s4_done %}{% assign done = true %}{% endif %} + {% if idx == 5 and s5_done %}{% assign done = true %}{% endif %} + + {%- comment -%} Current step is the first not-done stage {%- endcomment -%} + {% assign current = false %} + {% if current_idx == idx and done == false %} + {% assign current = true %} + {% endif %} + + {%- comment -%} Future steps: any stage to the right of current_idx {%- endcomment -%} + {% assign future = false %} + {% if idx > current_idx %} + {% assign future = true %} + {% endif %} + + {%- comment -%} + Class logic: + - Current: is-current + - Done & NOT future: is-done + - Otherwise (including done but future): is-pending + {%- endcomment -%} +
+
{{ s }}
+
+ {% if idx == 1 %} + Received ✓ + {% elsif idx == 2 %} + {% if leader_review_done and leader_review_status != "not placed" %}Approved{% elsif leader_review_status == "not placed" %}Application closed{% else %}Awaiting leader review{% endif %} + {% elsif idx == 3 %} + {% if bc_total > 0 %}{{ bc_complete }}/{{ bc_total }} complete{% else %}No check required{% endif %} + {% elsif idx == 4 %} + {% if req_total > 0 %}{{ req_complete }}/{{ req_total }} complete{% else %}{% endif %} + {% elsif idx == 5 %} + {% if ready_done %}All set!{% else %}Pending prior steps{% endif %} + {% endif %} +
+ +
+ {% endfor %} +
+
+ + + {% if is_closed == 0 %} + {% if any_bc or any_addl %} +
+

Requirements

+ + {% if any_bc %} +
+
Background Check
+ {% if background_checks and background_checks.size > 0 %} +
    + {% for bc in background_checks %} + {% assign s = bc["Background_Check_Status"] | default: "Needed" %} + {% assign s_l = s | downcase | strip %} + {% assign item_done = false %} + {% for w in YES_WORDS %} + {% assign w_t = w | downcase | strip %} + {% if w_t != "" and s_l contains w_t %} + {% assign item_done = true %} + {% endif %} + {% endfor %} + {% assign group_stage = 3 %} +
  • + + + {{ bc["Background_Check_Type"] | default: "Background Check" }} + {% assign bc_url = bc["Background_Check_URL"] | default: "" | strip %} + {% if item_done == false and bc_url != "" %} + + Complete Background Check + + {% endif %} + ({% if item_done %}Complete{% else %}{{ s }}{% endif %}) + +
  • + {% endfor %} +
+ {% else %} +

No background check required.

+ {% endif %} +
+ {% endif %} + + {% if any_addl %} +
+
Additional Requirements
+ {% assign any_addl = false %} + {% if milestones and milestones.size > 0 %}{% assign any_addl = true %}{% endif %} + {% if certifications and certifications.size > 0 %}{% assign any_addl = true %}{% endif %} + {% if forms and forms.size > 0 %}{% assign any_addl = true %}{% endif %} + + +
    + {% for m in milestones %} + {% assign s = m["Milestone_Status"] | default: "Needed" %} + {% assign s_l = s | downcase | strip %} + {% assign item_done = false %} + {% for w in YES_WORDS %} + {% assign w_t = w | downcase | strip %} + {% if w_t != "" and s_l contains w_t %} + {% assign item_done = true %} + {% endif %} + {% endfor %} + {% assign group_stage = 4 %} +
  • + + + Milestone: {{ m["Milestone_Title"] | default: "Milestone" }} + ({% if item_done %}Complete{% else %}{{ s }}{% endif %}) + +
  • + {% endfor %} + + {% for c in certifications %} + {% assign s = c["Certification_Status"] | default: "Needed" %} + {% assign s_l = s | downcase | strip %} + {% assign item_done = false %} + {% for w in YES_WORDS %} + {% assign w_t = w | downcase | strip %} + {% if w_t != "" and s_l contains w_t %} + {% assign item_done = true %} + {% endif %} + {% endfor %} + {% assign group_stage = 4 %} +
  • + + + Certification: {{ c["Certification_Type"] | default: "Certification" }} + ({% if item_done %}Complete{% else %}{{ s }}{% endif %}) + +
  • + {% endfor %} + + {% for f in forms %} + {% assign s = f["Form_Status"] | default: "Needed" %} + {% assign s_l = s | downcase | strip %} + {% assign item_done = false %} + {% for w in YES_WORDS %} + {% assign w_t = w | downcase | strip %} + {% if w_t != "" and s_l contains w_t %} + {% assign item_done = true %} + {% endif %} + {% endfor %} + {% assign group_stage = 4 %} +
  • + + + Form: {{ f["Form_Title"] | default: "Form" }} + {% assign form_url = f["Form_URL"] | default: "" | strip %} + {% if item_done == false and form_url != "" %} + Complete Form + {% endif %} + ({% if item_done %}Complete{% else %}{{ s }}{% endif %}) + +
  • + {% endfor %} + +
+
+ {% endif %} +
+ {% endif %} + {% endif %} + + + {% assign contact_first = vi["Opportunity_Contact_Nickname"] | default: "" %} + {% assign contact_last = vi["Opportunity_Contact_Last_Name"] | default: "" %} + {% assign contact_email = vi["Opportunity_Contact_Email"] | default: "" %} +
+

+ Have a question or need help completing requirements? + Contact {{ contact_first }} {{ contact_last }}. +

+
+
+ + +{% endif %} \ No newline at end of file diff --git a/Widgets/VolunteerTracker/demo.html b/Widgets/VolunteerTracker/demo.html new file mode 100644 index 0000000..9295c17 --- /dev/null +++ b/Widgets/VolunteerTracker/demo.html @@ -0,0 +1,26 @@ + + + Volunteer Tracker Widget Demo + + + + + + + + + +
+ + +