Repository: Techtonica/techtonica.org
Pull request #621: [Issue 381 & 379] code of conduct checkbox, validation, profanity checker, and successful submission
Author: login: daaimah123
Created: 2025-02-27T01:10:11Z | Merged: 2025-03-29T18:36:42Z

### 📝 Description
We don't want the user to be able to submit the form and their payment info if profanity is detected, we also want submission to acknowledge commitment to the code of conduct, handle form validation with clear indication of what is happening, and a successful submission view to remove the form. 

### 🔂 Changes Made
- Function to check text for profanity using PurgoMalum API, with focus on the first invalid field.
- Create a mapping of field IDs to readable labels.
- Checking for profanity error indication

### ⚙️ Related Issue
- Issue Number: #379 & #381

### 🍏 Type of Change
- New feature(s)

### 🎁 Acceptance Criteria
- Checks all user text input values for profanity in strings
- When profanity, notify user and prevent submission from going through and notify the user.
- Check for credit card information is entered, notifies user if missing
- Disabled submission button if code of conduct or credit card info not entered/selected
- Validation statements for missing required field inputs

### 🧪 How to test
- Ensure you have .env/config.ini variables. 
- Run instructions under [Square Testing in the README](https://github.com/Techtonica/techtonica.org?tab=readme-ov-file#square-testing)
  ```
  pip install pyopenssl
  FLASK_DEBUG=1 FLASK_APP=main_site.py FLASK_RUN_CERT=adhoc flask run
  ```
- Try to submit the form in the following ways
  - Input strings with combination of profanity and regular words to see if the form allows for submission (you should not be unable to submit, you should see either a red indication telling you to enter credit card information or identifying profane language)
  - Enter the [test card details](https://developer.squareup.com/docs/devtools/sandbox/payments) with all required fields entered, no profanity, with the checkbox selected (you should see a processing payment validation statement and get a successful screen)
  - Attempt to submit the form without the checkbox selected (you should be unable to)
  - Attempt to submit the form with the checkbox selected and no fields completed or selected (you should be unable to)
  - Attempt to submit the form with the checkbox selected, [test card details](https://developer.squareup.com/docs/devtools/sandbox/payments) entered, and no other required fields selected or input (you should be unable to, you should be prompted to enter the required field input)


Diff:
diff --git a/static/css/style.css b/static/css/style.css
index a8b604ca..fe6b6fdd 100644
--- a/static/css/style.css
+++ b/static/css/style.css
@@ -212,11 +212,7 @@ p {
 }
 
 .mc-closeModal {
-  text-shadow:
-    -1px -1px 0 #000,
-    1px -1px 0 #000,
-    -1px 1px 0 #000,
-    1px 1px 0 #000;
+  text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000;
 }
 
 .main-content {
@@ -236,8 +232,7 @@ p {
   justify-content: flex-end;
   width: 100%;
   height: 75vh;
-  background: url(../img/three-participants-at-laptops-min.jpg) #0093b5
-    no-repeat top right fixed;
+  background: url(../img/three-participants-at-laptops-min.jpg) #0093b5 no-repeat top right fixed;
   background-size: cover;
 }
 
@@ -284,8 +279,7 @@ p {
   justify-content: flex-end;
   width: 100%;
   height: 100vh;
-  background: url(../img/2024-H2-Launch-Celebration-min.png) #0093b5 no-repeat
-    top fixed;
+  background: url(../img/2024-H2-Launch-Celebration-min.png) #0093b5 no-repeat top fixed;
   background-size: cover;
 }
 
@@ -686,8 +680,7 @@ table.mentor td:first-of-type {
   .main-header {
     display: block;
     position: relative;
-    background: url(../img/three-participants-at-laptops-min.jpg) #0093b5
-      no-repeat top center;
+    background: url(../img/three-participants-at-laptops-min.jpg) #0093b5 no-repeat top center;
     -webkit-background-size: contain;
     -moz-background-size: contain;
     -o-background-size: contain;
@@ -737,8 +730,7 @@ table.mentor td:first-of-type {
     position: relative;
     /*create the upper and lower lines as pseudo-elements of the middle line*/
   }
-  .lines:before,
-  .lines:after {
+  .lines:before, .lines:after {
     display: inline-block;
     width: 3rem;
     height: 0.4285714286rem;
@@ -770,8 +762,7 @@ table.mentor td:first-of-type {
     background: transparent;
     /*overlay the lines by setting both their top values to 0*/
   }
-  .lines-button.x.close .lines:before,
-  .lines-button.x.close .lines:after {
+  .lines-button.x.close .lines:before, .lines-button.x.close .lines:after {
     transform-origin: 50% 50%;
     top: 0;
     width: 2.5em;
@@ -1089,13 +1080,17 @@ p.press-release-bold {
 }
 
 #payment-flow-message.error {
-  color: #bf0020;
-  font-size: 12px;
-  line-height: 14px;
+  color: #BF0020;
+  font-weight: bold;
+  margin-top: 10px;
+  font-size: 14px;
+  line-height: 1.4;
 }
 
 #payment-flow-message.success {
-  color: #3374ff;
+  color: #28a745;
+  font-weight: bold;
+  margin-top: 10px;
 }
 
 .wrapper {
@@ -1130,8 +1125,8 @@ legend {
   color: rgba(0, 115, 149, 0.8);
 }
 
-#info-wrapper > fieldset > input[type="text"],
-#info-wrapper > fieldset > input[type="email"],
+#info-wrapper > fieldset > input[type=text],
+#info-wrapper > fieldset > input[type=email],
 #info-wrapper > fieldset > textarea {
   min-width: 90%;
   margin: auto auto 1em auto;
@@ -1144,7 +1139,7 @@ legend {
   min-height: 6em;
 }
 
-input[type="radio"] {
+input[type=radio] {
   width: 50px;
 }
 
@@ -1156,6 +1151,7 @@ input[type="radio"] {
 
 #payment-page {
   padding: 1.5em;
+  background-color: #0093b5;
 }
 
 #payment-page > h1,
@@ -1182,6 +1178,21 @@ input[type="radio"] {
   list-style-type: none;
 }
 
+.checkbox-container {
+  margin: 25px;
+  padding-bottom: 30px;
+  display: flex;
+}
+
+input#code-of-conduct-checkbox {
+  margin-right: 15px;
+}
+
+label[for=code-of-conduct-checkbox] ~ a {
+  color: rgba(0, 115, 149, 0.8);
+  text-decoration: none;
+}
+
 @media (max-width: 900px) {
   .wrapper {
     max-width: 75%;
@@ -1223,5 +1234,116 @@ input[type="radio"] {
     margin: 20px;
   }
 }
+/* Invalid radio wrapper styling */
+#radio-wrapper.invalid {
+  padding: 10px;
+  background-color: rgba(255, 200, 200, 0.1);
+  border-radius: 4px;
+  border: 2px solid #BF0020;
+}
+
+/* Invalid checkbox container styling */
+.checkbox-container.invalid {
+  padding: 10px;
+  background-color: rgba(255, 200, 200, 0.1);
+  border-radius: 4px;
+  border: 2px solid #BF0020;
+}
+
+/* Disabled button styling */
+button:disabled,
+button.disabled {
+  opacity: 0.6;
+  cursor: not-allowed;
+}
+
+/* Success page styling */
+.success-container {
+  text-align: center;
+  padding: 40px 20px;
+  background-color: #fafafa;
+  border-radius: 8px;
+  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
+}
+
+.success-icon {
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: 80px;
+  height: 80px;
+  background-color: #28a745;
+  color: white;
+  font-size: 40px;
+  border-radius: 50%;
+  margin-bottom: 20px;
+}
+
+.success-container h2 {
+  color: #28a745;
+  margin-bottom: 20px;
+}
+
+.success-container p {
+  margin-bottom: 15px;
+  font-size: 18px;
+  line-height: 1.5;
+  color: #333;
+  text-align: center;
+}
+
+.success-container a {
+  color: #0093b5;
+  text-decoration: underline;
+}
+
+.success-container button {
+  margin-top: 30px;
+}
+
+/* Existing styles for invalid fields, etc. */
+input.invalid,
+textarea.invalid {
+  border: 2px solid #BF0020 !important;
+  background-color: rgba(255, 200, 200, 0.1);
+}
+
+/* Processing state styling */
+.processing {
+  position: relative;
+  pointer-events: none;
+}
+
+.processing::after {
+  content: "";
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  background-color: rgba(255, 255, 255, 0.7);
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  z-index: 10;
+}
+
+/* Spinner animation for processing state */
+@keyframes spinner {
+  to {
+    transform: rotate(360deg);
+  }
+}
+.spinner {
+  display: inline-block;
+  width: 20px;
+  height: 20px;
+  border: 3px solid rgba(0, 147, 181, 0.3);
+  border-radius: 50%;
+  border-top-color: #0093b5;
+  animation: spinner 0.8s linear infinite;
+  margin-right: 10px;
+  vertical-align: middle;
+}
 
 /*# sourceMappingURL=style.css.map */
diff --git a/static/css/style.css.map b/static/css/style.css.map
index 71cc8204..e96306ac 100644
--- a/static/css/style.css.map
+++ b/static/css/style.css.map
@@ -1 +1 @@
-{"version":3,"sourceRoot":"","sources":["../sass/_settings.scss","../sass/style.scss","../sass/_mixins.scss"],"names":[],"mappings":"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sWN;EACA;;;AAGF;EACE,OD3WM;EC4WN;EACA;;;AAGF;EACE,ODjXM;ECkXN;EACA;EACA;;;AAGF;EACE,OD1XW;;;AC6Xb;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAIJ;EACE;EACA;;;AAKJ;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;IACE;;EAGF;IACE;;EAGF;IACE;;;AAIJ;EACE;IACE;IACA;IACA;;EAGF;IC/cE,cDgdsB;IChdtB,WDgdsB;IChdtB,SDgdsB;IC5cxB,MD4cwB;;EAGxB;IACE;;EAGF;ICvdE,cDwdsB;ICxdtB,WDwdsB;ICxdtB,SDwdsB;ICpdxB,MDodwB;IACtB;;EAGF;IACE;IACA;;EAGF;ICjeE,uBDke+B;ICle/B,oBDke+B;ICle/B,kBDke+B;IC9djC,eD8diC;IAC/B,ODjeW;;ECmeX;IACE,kBDpeS;ICqeT,OD3eE;;EC+eN;IACE;;EAGF;IACE;IACA;;EAGF;IACE;IACA;IACA;IACA;IACA;IACA;;EAGF;IACE;;EAGF;IACE;IACA;;EAGF;IACE;IACA;IACA;IACA;;EAGF;IACE;IACA;IACA;IACA;IACA;;EAGF;IACE;IACA;IACA;IACA;;EAGF;IACE;IACA;IACA;IACA;IACA;;EAGF;IACE;IACA;IACA;IACA;;EAGF;IACE;IACA;IACA;IACA;IACA;;EAGF;IACE;;EAGF;IACE;;EAGF;IACE;IACA;IACA;IC9jBA,yBDgkBiC;IChkBjC,sBDgkBiC;IChkBjC,oBDgkBiC;IC5jBnC,iBD4jBmC;;EAGnC;IACE;IACA;IACA;IACA;IACA;;EAGF;IACE;;EAGF;IACE;;EAGF;IACE;;EAGF;IACE;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;EAEA;IACE;;EAGF;IACE;IACA;;EAIJ;IClmBA;IACA,OFPY;IEQZ;IACA,YFnBW;IEoBX;IACA,YFVW;IC0mBT;AAEA;;EACA;ICxmBF;IACA,OFPY;IEQZ;IACA,YFnBW;IEoBX;IACA,YFVW;ICgnBP;IACA;IACA;IACA;;EAGF;IACE;;EAGF;IACE;;EAIJ;IACE;;EAGE;IACE;;EAGF;IACE;;EAKN;AACE;IACA;AAEA;;EACA;IAEE;IACA;IACA;;EAIF;IACE;;EAGF;IACE;;EAIJ;IACE;;EAGF;IACE;IACA;;EAGF;IACE;;EAEF;AAAA;IAEE;IACA;;EAEF;IACE;;EAEF;IACE;;;AAKJ;EACE;IACE;IACA;IACA;IACA;IACA;;EAIF;IACE;IACA;IACA;IACA;IACA;IACA;;EAKF;IACE;IACA;IACA;IACA;;EAEA;IACE;IACA;;;AAMN;EACE;IACE;;;AAIJ;AACA;EACE;IACE;IACA;;;AAIJ;AACA;EACE;IACE;IACA;;EAGF;IACE;;;AAIJ;AACA;EACE;IACE;;EAGF;IACE;;;AAIJ;AACA;EACE;IACE;IACA;;EAGF;IACE;IACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,kBDpyBM;;;ACuyBR;EACE;EACA;EACA;EACA;EACA,kBDtyBa;;;ACyyBf;AAAA;EAEE;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE,ODvzBa;ECwzBb;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;AAEA;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE,OD51BU;EC61BV;EACA;EACA;EACA;EACA;;AAEA;EACE,ODl2BQ;;ACq2BV;EACE;EACA;;;AAIJ;EACE,OD52BU;;AC82BV;EACE;;;AAIJ;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE,ODt6BU;;;ACy6BZ;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EC/6BI,uBDg7B6B;ECh7B7B,oBDg7B6B;ECh7B7B,kBDg7B6B;EC56B/B,eD46B+B;EAC/B,ODr7BM;ECs7BN;EACA,kBDj7Ba;ECk7Bb;EACA;EACA;;AAEA;EACE,kBD/7BS;ECg8BT,OD97BI;EC+7BJ;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;AAAA;EAEE;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EAEA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;;;AAGF;AAAA;AAAA;EAGE;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;AAAA;EAEE;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;IACE;;EAGF;IACE;IACA;;;AAIJ;EACE;IACE;;EAGF;IACE;;EAGF;IACE;IACA;IACA;;EAGF;IACE;;EAGF;IACE;IACA;;EAGF;IACE;IACA;;EAGF;IACE;IACA;;EAGF;IACE;IACA","file":"style.css"}
\ No newline at end of file
+{"version":3,"sourceRoot":"","sources":["../sass/_settings.scss","../sass/style.scss","../sass/_mixins.scss"],"names":[],"mappings":";AAcA;EACE;EACA;EACA;EACA;;;AAGF;AAAA;AAAA;AAAA;AAAA;AAAA;EAME;EACA,OA5BU;EA6BV;EACA;;;AAGF;AAAA;EAEE;;;AAGF;AAAA;AAAA;AAAA;EAIE;;;AAGF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAQE;;;AAGF;EACE,OAtDM;EAuDN,aApDuB;EAqDvB;EACA;;;AAGF;EACE,OAhEU;EAiEV;;;AAGF;EACE,kBAlEM;EAmEN;;;AAGF;EACE,OAxEU;EAyEV,aAnEuB;;;AAsEzB;EACE,kBA/EU;EAgFV,OA7EM;;AA8EN;EACE;EACA;EACA,aA7EoB;;AA+EtB;EACE,OAtFS;;;AA0Fb;EACE;EACA,OA7FU;;;AAgGZ;EACE;;;AAGF;EACE;;;AAGF;EACE;;;ACtGF;ECII,iBDHuB;ECGvB,cDHuB;ECOzB,SDPyB;EACzB;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;ECfI,cDgBoB;EChBpB,WDgBoB;ECZtB,MDYsB;EACtB;;;AAGF;ECpBI,iBDqBuB;ECrBvB,cDqBuB;ECjBzB,SDiByB;EACzB;EACA;EACA;EACA;EACA;;;AAEF;EC5BI,iBD6BuB;EC7BvB,cD6BuB;ECzBzB,SDyByB;EACzB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,kBD1CM;EC2CN;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,YDxDM;;;AC2DR;EACE;EACA;EACA,aDzDuB;;;AC4DzB;EACE,ODpEW;;;ACuEb;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;;;AAIJ;EC9FI,cD+FoB;EC/FpB,WD+FoB;EC/FpB,SD+FoB;EC3FtB,MD2FsB;EACtB;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE,aACE;;;AAMJ;EACE;;;AAGF;ECrHI,yBDsH+B;ECtH/B,sBDsH+B;ECtH/B,oBDsH+B;EClHjC,iBDkHiC;ECtH/B,iBDuHuB;ECvHvB,cDuHuB;ECvHvB,YDuHuB;ECnHzB,SDmHyB;EACzB;EACA;EACA;EACA;EACA;EAEA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;IACE;IACA;;;AAIJ;EAEE;;AAGA;EALF;IAMI;;;;AAIJ;ECjKI,yBDkK+B;EClK/B,sBDkK+B;EClK/B,oBDkK+B;EC9JjC,iBD8JiC;EClK/B,iBDmKuB;ECnKvB,cDmKuB;ECnKvB,YDmKuB;EC/JzB,SD+JyB;EACzB;EACA;EACA;EACA;EACA;EAEA;;;AAGF;EC7KI,yBD8K+B;EC9K/B,sBD8K+B;EC9K/B,oBD8K+B;EC1KjC,iBD0KiC;EC9K/B,iBD+KuB;EC/KvB,cD+KuB;EC/KvB,YD+KuB;EC3KzB,SD2KyB;EACzB;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;;AAEA;EALF;IAMI;IACA;IACA;IACA;;;;AAIJ;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;AACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;AAAA;EAEE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;AAAA;AAAA;EC5TI,uBD+T6B;EC/T7B,oBD+T6B;EC/T7B,kBD+T6B;EC3T/B,eD2T+B;EAC/B,ODpUM;ECqUN;EACA,kBDhUa;ECiUb;;AAEA;AAAA;AAAA;EACE,kBD5US;EC6UT,OD3UI;EC4UJ;;;AAIJ;EACE,ODlVU;;;ACqVZ;EACE;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;AAEA;EACE,ODnWI;;;ACuWR;EACE,ODxWM;ECyWN;EACA;;;AAGF;EACE,OD9WM;EC+WN;EACA;;;AAGF;EACE,ODpXM;ECqXN;EACA;EACA;;;AAGF;EACE,OD7XW;;;ACgYb;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAIJ;EACE;EACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;IACE;;EAGF;IACE;;EAGF;IACE;;;AAIJ;EACE;IACE;IACA;IACA;;EAGF;ICjdE,cDkdsB;ICldtB,WDkdsB;ICldtB,SDkdsB;IC9cxB,MD8cwB;;EAGxB;IACE;;EAGF;ICzdE,cD0dsB;IC1dtB,WD0dsB;IC1dtB,SD0dsB;ICtdxB,MDsdwB;IACtB;;EAGF;IACE;IACA;;EAGF;ICneE,uBDoe+B;ICpe/B,oBDoe+B;ICpe/B,kBDoe+B;IChejC,eDgeiC;IAC/B,ODneW;;ECqeX;IACE,kBDteS;ICueT,OD7eE;;ECifN;IACE;;EAGF;IACE;IACA;;EAGF;IACE;IACA;IACA;IACA;IACA;IACA;;EAGF;IACE;;EAGF;IACE;IACA;;EAGF;IACE;IACA;IACA;IACA;;EAGF;IACE;IACA;IACA;IACA;IACA;;EAGF;IACE;IACA;IACA;IACA;;EAGF;IACE;IACA;IACA;IACA;IACA;;EAGF;IACE;IACA;IACA;IACA;;EAGF;IACE;IACA;IACA;IACA;IACA;;EAGF;IACE;;EAGF;IACE;;EAGF;IACE;IACA;IACA;IChkBA,yBDkkBiC;IClkBjC,sBDkkBiC;IClkBjC,oBDkkBiC;IC9jBnC,iBD8jBmC;;EAGnC;IACE;IACA;IACA;IACA;IACA;;EAGF;IACE;;EAGF;IACE;;EAGF;IACE;;EAGF;IACE;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;EAEA;IACE;;EAGF;IACE;IACA;;EAIJ;ICpmBA;IACA,OFPY;IEQZ;IACA,YFnBW;IEoBX;IACA,YFVW;IC4mBT;AAEA;;EACA;IC1mBF;IACA,OFPY;IEQZ;IACA,YFnBW;IEoBX;IACA,YFVW;ICknBP;IACA;IACA;IACA;;EAGF;IACE;;EAGF;IACE;;EAIJ;IACE;;EAGE;IACE;;EAGF;IACE;;EAKN;AACE;IACA;AAEA;;EACA;IAEE;IACA;IACA;;EAIF;IACE;;EAGF;IACE;;EAIJ;IACE;;EAGF;IACE;IACA;;EAGF;IACE;;EAEF;AAAA;IAEE;IACA;;EAEF;IACE;;EAEF;IACE;;;AAKJ;EACE;IACE;IACA;IACA;IACA;IACA;;EAIF;IACE;IACA;IACA;IACA;IACA;IACA;;EAIA;IACE;IACA;IACA;IACA;;EAEA;IACE;IACA;;;AAMR;EACE;IACE;;;AAIJ;AACA;EACE;IACE;IACA;;;AAIJ;AACA;EACE;IACE;IACA;;EAGF;IACE;;;AAIJ;AACA;EACE;IACE;;EAGF;IACE;;;AAIJ;AACA;EACE;IACE;IACA;;EAGF;IACE;IACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,kBDryBM;;;ACwyBR;EACE;EACA;EACA;EACA;EACA,kBDvyBa;;;AC0yBf;AAAA;EAEE;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE,ODxzBa;ECyzBb;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;AAEA;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE,OD71BU;EC81BV;EACA;EACA;EACA;EACA;;AAEA;EACE,ODn2BQ;;ACs2BV;EACE;EACA;;;AAIJ;EACE,OD72BU;;AC+2BV;EACE;;;AAIJ;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE,ODv6BU;;;AC06BZ;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;ECh7BI,uBDi7B6B;ECj7B7B,oBDi7B6B;ECj7B7B,kBDi7B6B;EC76B/B,eD66B+B;EAC/B,ODt7BM;ECu7BN;EACA,kBDl7Ba;ECm7Bb;EACA;EACA;;AAEA;EACE,kBDh8BS;ECi8BT,OD/7BI;ECg8BJ;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;AAAA;EAEE;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EAEA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;;;AAGF;AAAA;AAAA;EAGE;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;AAAA;EAEE;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;IACE;;EAGF;IACE;IACA;;;AAIJ;EACE;IACE;;EAGF;IACE;;EAGF;IACE;IACA;IACA;;EAGF;IACE;;EAGF;IACE;IACA;;EAGF;IACE;IACA;;EAGF;IACE;IACA;;EAGF;IACE;IACA;;;AAIJ;AACA;EACE;EACA;EACA;EACA;;;AAGF;AACA;EACE;EACA;EACA;EACA;;;AAGF;AACA;AAAA;EAEE;EACA;;;AAGF;AACA;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAGF;AACA;AAAA;EAEE;EACA;;;AAGF;AACA;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;AACA;EACE;IAAI;;;AAGN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA","file":"style.css"}
\ No newline at end of file
diff --git a/static/js/payment-flow.js b/static/js/payment-flow.js
index af5b98ab..1908e3bf 100644
--- a/static/js/payment-flow.js
+++ b/static/js/payment-flow.js
@@ -1,8 +1,8 @@
 async function SquarePaymentFlow() {
   // Create card payment object and attach to page
   CardPay(
-    document.getElementById("card-container"),
-    document.getElementById("card-button"),
+    document.getElementById('card-container'),
+    document.getElementById('card-button')
   );
 }
 
@@ -22,7 +22,212 @@ window.showError = function (message) {
   window.paymentFlowMessageEl.innerText = message;
 };
 
-window.createPayment = async function (token) {
+// Function to display success page after payment
+window.showSuccessPage = function(jobTitle, company) {
+  // Get the form container
+  const formContainer = document.getElementById('fast-checkout');
+  
+  // Create success content
+  const successContent = document.createElement('div');
+  successContent.className = 'success-container';
+  successContent.innerHTML = `
+    <div class="success-icon">✓</div>
+    <h2>Payment Successful!</h2>
+    <p>Thank you for submitting your job posting for "${jobTitle}" at "${company}".</p>
+    <p>If approved, your job will be shared with our graduates who have 0-5 years of experience.</p>
+    <p>If you have any questions, please contact us at <a href="mailto:info@techtonica.org">info@techtonica.org</a>.</p>
+    <button id="post-another-job" class="sponsor">
+      <h2>Post Another Job</h2>
+    </button>
+  `;
+  
+  // Clear the form container and append success content
+  formContainer.innerHTML = '';
+  formContainer.appendChild(successContent);
+  
+  // Add event listener to "Post Another Job" button
+  document.getElementById('post-another-job').addEventListener('click', function() {
+    // Reload the page to start fresh
+    window.location.reload();
+  });
+  
+  // Scroll to top of success message
+  window.scrollTo({
+    top: formContainer.offsetTop - 100,
+    behavior: 'smooth'
+  });
+}
+
+// Function to check text for profanity using PurgoMalum API with improved word boundary handling
+window.checkProfanity = async function(text) {
+  if (!text || text.trim() === '') return { containsProfanity: false };
+  
+  try {
+    // Split the text into words to check them individually
+    // This helps avoid false positives in names like "Harshitha"
+    const words = text.split(/\s+/);
+    
+    // Check each word individually
+    for (const word of words) {
+      // Skip very short words (likely not profanity)
+      if (word.length <= 2) continue;
+      
+      // Skip words that look like they might be names (first letter capitalized)
+      // This is a simple heuristic to reduce false positives on names
+      if (/^[A-Z][a-z]+$/.test(word)) continue;
+      
+      // Encode the word for URL
+      const encodedWord = encodeURIComponent(word);
+      
+      // Use PurgoMalum's containsprofanity endpoint for this specific word
+      const response = await fetch(`https://www.purgomalum.com/service/containsprofanity?text=${encodedWord}`);
+      const result = await response.text();
+      
+      if (result.trim() === 'true') {
+        return { 
+          containsProfanity: true,
+          text: word // Return the specific word that was flagged
+        };
+      }
+    }
+    
+    // If we get here, no individual word was flagged
+    return { containsProfanity: false };
+  } catch (error) {
+    console.error('Error checking profanity:', error);
+    // If the API fails, we'll let the text pass to not block users
+    return { containsProfanity: false };
+  }
+}
+
+// Validate form fields
+window.validateForm = async function() {
+  const requiredFields = [
+    'firstname', 'lastname', 'email', 'jobtitle', 
+    'company', 'location'
+  ];
+  
+  let isValid = true;
+  let firstInvalidField = null;
+  
+  // Check all required fields
+  for (const fieldId of requiredFields) {
+    const field = document.getElementById(fieldId);
+    if (!field.value.trim()) {
+      field.classList.add('invalid');
+      isValid = false;
+      if (!firstInvalidField) firstInvalidField = field;
+    } else {
+      field.classList.remove('invalid');
+    }
+  }
+  
+  // Validate email format
+  const emailField = document.getElementById('email');
+  const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
+  if (emailField.value.trim() && !emailPattern.test(emailField.value)) {
+    emailField.classList.add('invalid');
+    isValid = false;
+    if (!firstInvalidField) firstInvalidField = emailField;
+  }
+  
+  // Check if referral radio is selected
+  const referralRadios = document.getElementsByName('referral');
+  let referralSelected = false;
+  referralRadios.forEach(radio => {
+    if (radio.checked) {
+      referralSelected = true;
+    }
+  });
+  
+  if (!referralSelected) {
+    document.getElementById('radio-wrapper').classList.add('invalid');
+    isValid = false;
+    if (!firstInvalidField) firstInvalidField = document.getElementById('radio-wrapper');
+  } else {
+    document.getElementById('radio-wrapper').classList.remove('invalid');
+  }
+  
+  // Check if code of conduct checkbox is checked
+  const conductCheckbox = document.getElementById('code-of-conduct-checkbox');
+  if (!conductCheckbox.checked) {
+    conductCheckbox.parentElement.classList.add('invalid');
+    isValid = false;
+    // Make the checkbox a priority for focus if it's not checked
+    firstInvalidField = conductCheckbox;
+  } else {
+    conductCheckbox.parentElement.classList.remove('invalid');
+  }
+  
+  // If basic validation fails, return early before checking profanity
+  if (!isValid) {
+    if (firstInvalidField) {
+      firstInvalidField.focus();
+      window.showError('Please fill in all required fields and accept the Code of Conduct.');
+    }
+    return false;
+  }
+  
+  // Show loading message while checking profanity
+  window.showError('Checking content for inappropriate language...');
+  
+  // Get all text inputs and textareas in the form
+  const form = document.getElementById('fast-checkout');
+  const textInputs = form.querySelectorAll('input[type="text"], input[type="email"], textarea');
+  
+  // Create a mapping of field IDs to readable labels
+  const fieldLabels = {
+    'firstname': 'First Name',
+    'lastname': 'Last Name',
+    'email': 'Email',
+    'jobtitle': 'Job Title',
+    'company': 'Company',
+    'type': 'Type',
+    'educationreq': 'Education Requirement',
+    'location': 'Location',
+    'salaryrange': 'Salary Range',
+    'description': 'Description',
+    'applicationlink': 'Application Link'
+  };
+  
+  // Check each text field for profanity
+  for (const input of textInputs) {
+    const text = input.value.trim();
+    
+    if (text) {
+      const profanityCheck = await window.checkProfanity(text);
+      
+      if (profanityCheck.containsProfanity) {
+        input.classList.add('invalid');
+        isValid = false;
+        if (!firstInvalidField) firstInvalidField = input;
+        
+        // Get a readable label for the field
+        const fieldLabel = fieldLabels[input.id] || input.id;
+        window.showError(`Potentially inappropriate word "${profanityCheck.text}" detected in ${fieldLabel}. Please revise your content.`);
+        break; // Stop checking after first profanity found
+      }
+    }
+  }
+  
+  // If profanity was found, focus the first invalid field
+  if (!isValid && firstInvalidField) {
+    firstInvalidField.focus();
+    return false;
+  }
+  
+  // Clear the "checking content" message if everything is valid
+  window.paymentFlowMessageEl.innerText = '';
+  return true;
+}
+
+window.createPayment = async function(token) {
+  // If we have a token, the card info must be complete
+  // No need to check window.cardInfoComplete here
+  
+  // Show processing message
+  window.showError('Processing payment...');
+  
   const dataJsonString = JSON.stringify({
     token,
     idempotencyKey: window.idempotencyKey,
@@ -46,33 +251,40 @@ window.createPayment = async function (token) {
         window.showError("Payment Failed.");
       }
     } else {
-      window.showSuccess("Payment Successful!");
-
-      window.sendSlackNotification();
+      // Get job title and company for the success message
+      const jobTitle = document.getElementById('jobtitle').value;
+      const company = document.getElementById('company').value;
+      
+      // Send notification to Slack
+      await window.sendSlackNotification();
+      
+      // Show success page (this replaces the form)
+      window.showSuccessPage(jobTitle, company);
     }
   } catch (error) {
-    console.error("Error:", error);
+    console.error('Error:', error);
+    window.showError('An error occurred while processing your payment.');
   }
 };
 
 window.sendSlackNotification = async function () {
   var referralValue = "no";
 
-  document.getElementsByName("referral").forEach((radio) => {
-    if (radio.checked) {
+  document.getElementsByName("referral").forEach(radio => {
+    if(radio.checked){
       referralValue = radio.value;
     }
   });
 
   var notificationValues = {
-    firstName: document.getElementById("firstname").value,
-    lastName: document.getElementById("lastname").value,
-    email: document.getElementById("email").value,
-    jobTitle: document.getElementById("jobtitle").value,
-    company: document.getElementById("company").value,
-    type: document.getElementById("type").value,
-    educationReq: document.getElementById("educationreq").value,
-    location: document.getElementById("location").value,
+    firstName: document.getElementById('firstname').value,
+    lastName: document.getElementById('lastname').value,
+    email: document.getElementById('email').value,
+    jobTitle: document.getElementById('jobtitle').value,
+    company: document.getElementById('company').value,
+    type: document.getElementById('type').value,
+    educationReq: document.getElementById('educationreq').value,
+    location: document.getElementById('location').value,
     referral: referralValue,
     salaryRange: document.getElementById("salaryrange").value,
     description: document.getElementById("description").value,
@@ -82,16 +294,91 @@ window.sendSlackNotification = async function () {
   var dataJsonString = JSON.stringify(notificationValues);
 
   try {
-    const response = await fetch("/send-posting", {
-      method: "POST",
+    const response = await fetch('/send-posting', {
+      method: 'POST',
       headers: {
-        "Content-Type": "application/json",
+        'Content-Type': 'application/json'
       },
-      body: dataJsonString,
+      body: dataJsonString
     });
+    return true;
   } catch (error) {
-    console.error("Error:", error);
+    console.error('Error:', error);
+    return false;
   }
-};
+}
+
+// Form and code of conduct checkbox functionality
+document.addEventListener("DOMContentLoaded", () => {
+  // Initialize the cardInfoComplete flag
+  window.cardInfoComplete = false;
+  
+  const termsCheckbox = document.getElementById("code-of-conduct-checkbox");
+  const cardButton = document.getElementById("card-button");
+  const cardContainer = document.getElementById('card-container');
+  
+  // Set initial button state
+  cardButton.disabled = !termsCheckbox.checked;
+  
+  // Visual indicator for disabled state
+  if (cardButton.disabled) {
+    cardButton.classList.add('disabled');
+  } else {
+    cardButton.classList.remove('disabled');
+  }
+  
+  // Add visual indicator for card container
+  if (cardContainer) {
+    // Add a subtle border that changes color when card info is complete
+    cardContainer.style.transition = 'border-color 0.3s ease';
+  }
+  
+  termsCheckbox.addEventListener("change", function() {
+    cardButton.disabled = !this.checked;
+    
+    if (this.checked) {
+      cardButton.classList.remove('disabled');
+      this.parentElement.classList.remove('invalid');
+      window.paymentFlowMessageEl.innerText = '';
+    } else {
+      cardButton.classList.add('disabled');
+    }
+  });
+  
+  // Input event listeners to clear error styling when user types
+  const allInputs = document.querySelectorAll('input, textarea');
+  allInputs.forEach(input => {
+    input.addEventListener('input', function() {
+      this.classList.remove('invalid');
+      if (this.parentElement.classList.contains('checkbox-container')) {
+        this.parentElement.classList.remove('invalid');
+      }
+      window.paymentFlowMessageEl.innerText = '';
+    });
+  });
+  
+  // Add listeners for radio buttons
+  const referralRadios = document.getElementsByName('referral');
+  referralRadios.forEach(radio => {
+    radio.addEventListener('change', function() {
+      document.getElementById('radio-wrapper').classList.remove('invalid');
+    });
+  });
+  
+  // Prevent form submission if validation fails
+  document.getElementById('fast-checkout').addEventListener('submit', async function(e) {
+    e.preventDefault(); // Always prevent default to handle validation
+    
+    // First validate the form fields
+    const isFormValid = await window.validateForm();
+    if (!isFormValid) {
+      return;
+    }
+    
+    // If form is valid, let the card button handle the payment
+    // This will trigger the eventHandler in sq-card-pay.js
+    document.getElementById('card-button').click();
+  });
+});
 
-SquarePaymentFlow();
+SquarePaymentFlow();
\ No newline at end of file
diff --git a/static/js/sq-card-pay.js b/static/js/sq-card-pay.js
index 31ece747..29d3ade8 100644
--- a/static/js/sq-card-pay.js
+++ b/static/js/sq-card-pay.js
@@ -2,23 +2,37 @@ async function CardPay(fieldEl, buttonEl) {
   // Create a card payment object and attach to page
   const card = await window.payments.card({
     style: {
-      ".input-container.is-focus": {
-        borderColor: "#006AFF",
+      '.input-container.is-focus': {
+        borderColor: '#006AFF'
       },
-      ".message-text.is-error": {
-        color: "#BF0020",
-      },
-    },
+      '.message-text.is-error': {
+        color: '#BF0020'
+      }
+    }
   });
   await card.attach(fieldEl);
 
   async function eventHandler(event) {
     // Clear any existing messages
-    window.paymentFlowMessageEl.innerText = "";
+    window.paymentFlowMessageEl.innerText = '';
+    
+    // Check if the checkbox is checked first, before other validation
+    const conductCheckbox = document.getElementById('code-of-conduct-checkbox');
+    if (!conductCheckbox.checked) {
+      conductCheckbox.parentElement.classList.add('invalid');
+      conductCheckbox.focus();
+      window.showError('Please accept the Code of Conduct to proceed.');
+      return;
+    }
+    
+    // Then validate the rest of the form
+    if (!window.validateForm()) {
+      return;
+    }
 
     try {
       const result = await card.tokenize();
-      if (result.status === "OK") {
+      if (result.status === 'OK') {
         // Use global method from sq-payment-flow.js
         window.createPayment(result.token);
       }
@@ -26,10 +40,10 @@ async function CardPay(fieldEl, buttonEl) {
       if (e.message) {
         window.showError(`Error: ${e.message}`);
       } else {
-        window.showError("Something went wrong");
+        window.showError('Something went wrong');
       }
     }
   }
 
-  buttonEl.addEventListener("click", eventHandler);
+  buttonEl.addEventListener('click', eventHandler);
 }
diff --git a/static/sass/style.scss b/static/sass/style.scss
index 6481ca04..e98a8af3 100644
--- a/static/sass/style.scss
+++ b/static/sass/style.scss
@@ -1016,13 +1016,17 @@ p.press-release-bold {
 }
 
 #payment-flow-message.error {
-  color: #bf0020;
-  font-size: 12px;
-  line-height: 14px;
+  color: #BF0020;
+  font-weight: bold;
+  margin-top: 10px;
+  font-size: 14px;
+  line-height: 1.4;
 }
 
 #payment-flow-message.success {
-  color: #3374ff;
+  color: #28a745;
+  font-weight: bold;
+  margin-top: 10px;
 }
 
 .wrapper {
@@ -1084,6 +1088,7 @@ input[type="radio"] {
 
 #payment-page {
   padding: 1.5em;
+  background-color: #0093b5;
 }
 
 #payment-page > h1,
@@ -1109,6 +1114,21 @@ input[type="radio"] {
   list-style-type: none;
 }
 
+.checkbox-container {
+  margin: 25px;
+  padding-bottom: 30px;
+  display: flex;
+}
+
+input#code-of-conduct-checkbox{
+  margin-right: 15px;
+}
+
+label[for="code-of-conduct-checkbox"] ~ a {
+  color: #007395cc;
+  text-decoration: none;
+}
+
 @media (max-width: 900px) {
   .wrapper {
     max-width: 75%;
@@ -1159,3 +1179,114 @@ input[type="radio"] {
     margin: 20px;
   }
 }
+
+/* Invalid radio wrapper styling */
+#radio-wrapper.invalid {
+  padding: 10px;
+  background-color: rgba(255, 200, 200, 0.1);
+  border-radius: 4px;
+  border: 2px solid #BF0020;
+}
+
+/* Invalid checkbox container styling */
+.checkbox-container.invalid {
+  padding: 10px;
+  background-color: rgba(255, 200, 200, 0.1);
+  border-radius: 4px;
+  border: 2px solid #BF0020;
+}
+
+/* Disabled button styling */
+button:disabled,
+button.disabled {
+  opacity: 0.6;
+  cursor: not-allowed;
+}
+
+/* Success page styling */
+.success-container {
+  text-align: center;
+  padding: 40px 20px;
+  background-color: #fafafa;
+  border-radius: 8px;
+  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
+}
+
+.success-icon {
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: 80px;
+  height: 80px;
+  background-color: #28a745;
+  color: white;
+  font-size: 40px;
+  border-radius: 50%;
+  margin-bottom: 20px;
+}
+
+.success-container h2 {
+  color: #28a745;
+  margin-bottom: 20px;
+}
+
+.success-container p {
+  margin-bottom: 15px;
+  font-size: 18px;
+  line-height: 1.5;
+  color: #333;
+  text-align: center;
+}
+
+.success-container a {
+  color: #0093b5;
+  text-decoration: underline;
+}
+
+.success-container button {
+  margin-top: 30px;
+}
+
+/* Existing styles for invalid fields, etc. */
+input.invalid,
+textarea.invalid {
+  border: 2px solid #BF0020 !important;
+  background-color: rgba(255, 200, 200, 0.1);
+}
+
+/* Processing state styling */
+.processing {
+  position: relative;
+  pointer-events: none;
+}
+
+.processing::after {
+  content: "";
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  background-color: rgba(255, 255, 255, 0.7);
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  z-index: 10;
+}
+
+/* Spinner animation for processing state */
+@keyframes spinner {
+  to {transform: rotate(360deg);}
+}
+
+.spinner {
+  display: inline-block;
+  width: 20px;
+  height: 20px;
+  border: 3px solid rgba(0, 147, 181, 0.3);
+  border-radius: 50%;
+  border-top-color: #0093b5;
+  animation: spinner 0.8s linear infinite;
+  margin-right: 10px;
+  vertical-align: middle;
+}
\ No newline at end of file
diff --git a/templates/job-form.html b/templates/job-form.html
index e1197ac6..07419f14 100644
--- a/templates/job-form.html
+++ b/templates/job-form.html
@@ -11,7 +11,7 @@
   window.idempotencyKey = "{{ idempotencyKey }}";
 </script>
 
-<div id="payment-page" class="blue-background">
+<div id="payment-page">
   <h1>Post A Job</h1>
   <p>
     Have a job opening but your company isn’t ready to become a hiring partner?
@@ -104,6 +104,18 @@ <h3>Job Listing Form</h3>
           </div> -->
         <h3>Payment Info</h3>
         <div id="card-container"></div>
+        <div class="checkbox-container">
+          <input type="checkbox" id="code-of-conduct-checkbox" required>
+          <label for="code-of-conduct-checkbox">
+            By checking this box, you agree that what you are submitting in this form adheres to 
+            <a
+              href="{{ url_for('render_conduct_page') }}"
+              title="Code of Conduct"
+              target="_blank"
+              rel="noopener noreferrer"
+              >Techtonica's Code of Conduct</a>.
+          </label>
+        </div>
         <button id="card-button" type="button" class="sponsor">
           <h2>Pay with Card</h2>
         </button>


Reviews:
user: login: kaylahrose
body: Some questions and change requests 🥳 
state: DISMISSED
author_association: COLLABORATOR
submitted_at: 2025-02-28T21:40:01Z
user: login: daaimah123
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-03T23:16:31Z
user: login: daaimah123
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-03T23:17:26Z
user: login: daaimah123
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-03T23:26:12Z
user: login: daaimah123
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-03T23:26:31Z
user: login: daaimah123
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-15T00:02:25Z
user: login: daaimah123
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-15T00:09:34Z
user: login: monikkaelyse
body: Link looks good now! But the code that is supposed to block submitting is not working for me. I assume this should just be replaced by the validation (or those features go in at the same time?). So suggestion to remove that chunk of code and just put validation in the other ticket, or fix this and then remove it when the validation code goes in.
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-15T21:57:06Z
user: login: daaimah123
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-20T19:58:06Z
user: login: daaimah123
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-20T19:58:35Z
user: login: daaimah123
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-20T20:00:42Z
user: login: monikkaelyse
body: Validation is working for me now ! Only last issue I see is that the button does not get disabled after submitting, so I can click it multiple times and keep submit (which all fail after the first). Is disabling that out of scope? Approving in the meantime
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-03-20T20:26:50Z
user: login: MichelleGlauser
state: APPROVED
author_association: MEMBER
submitted_at: 2025-03-21T18:38:05Z
user: login: ChasVanDav
body: @daaimah123 It's working well for me! 
<img width="612" alt="Screenshot 2025-03-25 at 2 03 39 PM" src="https://github.com/user-attachments/assets/b36481dd-3997-48bf-afd2-2f5bb376c0a2" />
<img width="614" alt="Screenshot 2025-03-25 at 2 03 49 PM" src="https://github.com/user-attachments/assets/991c4abe-899e-46f0-ae02-622dea91ba18" />
However, I do wonder if it is too strict?
How about refactoring so that it only flags it if it separated by a space or special character? One edge case is that my best friend's name is Harshitha and she is of Indian decent. So, there may be some cases like this
<img width="516" alt="Screenshot 2025-03-25 at 2 04 33 PM"  src="https://github.com/user-attachments/assets/cf09efc8-9017-4d5e-99bb-a3591989f358" />
 where someone's real name wouldn't pass this test. 
 
 
 N.B. For anyone having trouble running the website, I did the following:
 1. run `pip compile -U requirements.in` then `pip install -r requirements.txt` to make sure all dependencies are in there and up-to-date in local virtual environment.
 2. run `openssl req -x509 -newkey rsa:4096 -nodes -out cert.pem -keyout key.pem -days 365` to generate a certificate to bypass web security issues related to Square configuration (payment method). 
Complete the prompts with personal information. Two files `cert.pem` & `key.pem` should generate and appear in project directory.
 3. run `FLASK_DEBUG=1 FLASK_APP=main_site.py flask run --cert cert.pem --key key.pem `
 Be sure to copy/paste `https://127.0.0.1:5000` into an incognito browser, click "Advanced" then, finally click "Proceed to 127.0.0.1 (unsafe)".


state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-25T18:09:48Z
user: login: ChasVanDav
body: Great job on handling edge cases like diverse names! This worked for the case of Harshitha! @daaimah123 🚀 
<img width="711" alt="Screenshot 2025-03-27 at 6 12 02 PM" src="https://github.com/user-attachments/assets/428cd43b-aeed-4e26-ad4e-2574743ecfad" />
<img width="771" alt="Screenshot 2025-03-27 at 6 12 11 PM" src="https://github.com/user-attachments/assets/2bed0aa8-fe5f-480c-9814-2453cf621ebf" />

state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-03-27T22:18:16Z

Review comments:
diff_hunk: @@ -93,6 +93,20 @@ <h3>Job Listing Form</h3>
         </div> -->
         <h3>Payment Info</h3>
         <div id="card-container"></div>
+        <div class="checkbox-container">
+          <input type="checkbox" id="code-of-conduct-checkbox">
+          <label for="code-of-conduct-checkbox">
+            You agree to 
+            <a id="code-of-conduct-checkbox-link" href="{{ url_for('render_conduct_page') }}"
+              title="Code of Conduct"
+              target="_blank"
+              rel="noopener noreferrer"
+              >
+              Techtonica's Code of Conduct
+            </a>
+            by submitting this form.
path: templates/job-form.html
user: login: kaylahrose
body: If the action we want the user to take to provide consent is clicking the submit form button, we should remove the checkbox and keep the text. Consenting via form submission is implicit consent. However, if the action we would like the user to perform is checking the box, we should change the language to "By checking this box, you are agreeing to our Code of Conduct" or something like that. That is explicit consent, which is preferred.
created_at: 2025-02-28T21:14:17Z
author_association: COLLABORATOR
diff_hunk: @@ -93,6 +93,20 @@ <h3>Job Listing Form</h3>
         </div> -->
         <h3>Payment Info</h3>
         <div id="card-container"></div>
+        <div class="checkbox-container">
+          <input type="checkbox" id="code-of-conduct-checkbox">
+          <label for="code-of-conduct-checkbox">
+            You agree to 
+            <a id="code-of-conduct-checkbox-link" href="{{ url_for('render_conduct_page') }}"
+              title="Code of Conduct"
+              target="_blank"
+              rel="noopener noreferrer"
+              >
path: templates/job-form.html
user: login: kaylahrose
body: Can you please update the link style match the [style guide](https://www.dropbox.com/scl/fo/sb8ppa0qxuuott515euei/AEG3sWxuiJ8JfU36n35H7E0?e=2&preview=Techtonica_UI_design_kit_rev1.pdf&rlkey=kasmils5rmaqv199ggoh2us5p&dl=0)?
created_at: 2025-02-28T21:17:33Z
author_association: COLLABORATOR
diff_hunk: @@ -93,6 +93,20 @@ <h3>Job Listing Form</h3>
         </div> -->
         <h3>Payment Info</h3>
         <div id="card-container"></div>
+        <div class="checkbox-container">
+          <input type="checkbox" id="code-of-conduct-checkbox">
path: templates/job-form.html
user: login: kaylahrose
body: Can you please separate the checkbox from the text like the photo attached
<img width="574" alt="Screenshot 2025-02-28 at 1 19 30 PM" src="https://github.com/user-attachments/assets/a2cbdff8-f982-4677-b7c0-ea258e7df476" />


created_at: 2025-02-28T21:21:51Z
author_association: COLLABORATOR
diff_hunk: @@ -93,6 +93,20 @@ <h3>Job Listing Form</h3>
         </div> -->
         <h3>Payment Info</h3>
         <div id="card-container"></div>
+        <div class="checkbox-container">
+          <input type="checkbox" id="code-of-conduct-checkbox">
path: templates/job-form.html
user: login: kaylahrose
body: Can you please add spacing between the button and the text on smaller screen sizes?
<img width="633" alt="Screenshot 2025-02-28 at 1 12 37 PM" src="https://github.com/user-attachments/assets/1893febc-cbb6-460d-95df-a538f30287a4" />
created_at: 2025-02-28T21:23:32Z
author_association: COLLABORATOR
diff_hunk: @@ -93,6 +93,20 @@ <h3>Job Listing Form</h3>
         </div> -->
         <h3>Payment Info</h3>
         <div id="card-container"></div>
+        <div class="checkbox-container">
+          <input type="checkbox" id="code-of-conduct-checkbox">
path: templates/job-form.html
user: login: kaylahrose
body: Checkbox is not keyboard accessible, not sure if that is blocking though.
created_at: 2025-02-28T21:24:01Z
author_association: COLLABORATOR
diff_hunk: @@ -93,6 +93,20 @@ <h3>Job Listing Form</h3>
         </div> -->
         <h3>Payment Info</h3>
         <div id="card-container"></div>
+        <div class="checkbox-container">
+          <input type="checkbox" id="code-of-conduct-checkbox">
path: templates/job-form.html
user: login: kaylahrose
body: Can we make the checkbox required?
created_at: 2025-02-28T21:25:54Z
author_association: COLLABORATOR
diff_hunk: @@ -93,6 +93,20 @@ <h3>Job Listing Form</h3>
         </div> -->
         <h3>Payment Info</h3>
         <div id="card-container"></div>
+        <div class="checkbox-container">
+          <input type="checkbox" id="code-of-conduct-checkbox">
+          <label for="code-of-conduct-checkbox">
+            You agree to 
+            <a id="code-of-conduct-checkbox-link" href="{{ url_for('render_conduct_page') }}"
+              title="Code of Conduct"
+              target="_blank"
+              rel="noopener noreferrer"
+              >
+              Techtonica's Code of Conduct
+            </a>
+            by submitting this form.
+          </label>
+        </div>
         <button id="card-button" type="button" class="sponsor">
path: templates/job-form.html
user: login: kaylahrose
body: Form validation is not working on submit for me
created_at: 2025-02-28T21:39:03Z
author_association: COLLABORATOR
diff_hunk: @@ -93,6 +93,20 @@ <h3>Job Listing Form</h3>
         </div> -->
         <h3>Payment Info</h3>
         <div id="card-container"></div>
+        <div class="checkbox-container">
+          <input type="checkbox" id="code-of-conduct-checkbox">
path: templates/job-form.html
user: login: daaimah123
body: [See comment.](https://github.com/Techtonica/techtonica.org/pull/621#issuecomment-2695782638)
created_at: 2025-03-03T23:16:31Z
author_association: COLLABORATOR
diff_hunk: @@ -93,6 +93,20 @@ <h3>Job Listing Form</h3>
         </div> -->
         <h3>Payment Info</h3>
         <div id="card-container"></div>
+        <div class="checkbox-container">
+          <input type="checkbox" id="code-of-conduct-checkbox">
path: templates/job-form.html
user: login: daaimah123
body: [See comment.](https://github.com/Techtonica/techtonica.org/pull/621#issuecomment-2695782638)
created_at: 2025-03-03T23:17:26Z
author_association: COLLABORATOR
diff_hunk: @@ -93,6 +93,20 @@ <h3>Job Listing Form</h3>
         </div> -->
         <h3>Payment Info</h3>
         <div id="card-container"></div>
+        <div class="checkbox-container">
+          <input type="checkbox" id="code-of-conduct-checkbox">
path: templates/job-form.html
user: login: daaimah123
body: Addressed in [00bfa38](https://github.com/Techtonica/techtonica.org/pull/621/commits/00bfa38f72a2515b1d26ddd61fae60f67a722e94)
created_at: 2025-03-03T23:26:12Z
author_association: COLLABORATOR
diff_hunk: @@ -93,6 +93,20 @@ <h3>Job Listing Form</h3>
         </div> -->
         <h3>Payment Info</h3>
         <div id="card-container"></div>
+        <div class="checkbox-container">
+          <input type="checkbox" id="code-of-conduct-checkbox">
+          <label for="code-of-conduct-checkbox">
+            You agree to 
+            <a id="code-of-conduct-checkbox-link" href="{{ url_for('render_conduct_page') }}"
+              title="Code of Conduct"
+              target="_blank"
+              rel="noopener noreferrer"
+              >
+              Techtonica's Code of Conduct
+            </a>
+            by submitting this form.
path: templates/job-form.html
user: login: daaimah123
body: [See comment.](https://github.com/Techtonica/techtonica.org/pull/621#issuecomment-2695782638)
created_at: 2025-03-03T23:26:31Z
author_association: COLLABORATOR
diff_hunk: @@ -93,6 +93,20 @@ <h3>Job Listing Form</h3>
         </div> -->
         <h3>Payment Info</h3>
         <div id="card-container"></div>
+        <div class="checkbox-container">
+          <input type="checkbox" id="code-of-conduct-checkbox">
+          <label for="code-of-conduct-checkbox">
+            You agree to 
+            <a id="code-of-conduct-checkbox-link" href="{{ url_for('render_conduct_page') }}"
+              title="Code of Conduct"
+              target="_blank"
+              rel="noopener noreferrer"
+              >
path: templates/job-form.html
user: login: daaimah123
body: Done in [7d1a787](https://github.com/Techtonica/techtonica.org/pull/621/commits/7d1a7877bf459fc4031ca389252505b47074bf9c) and [eb693d6](https://github.com/Techtonica/techtonica.org/pull/621/commits/eb693d6f61216b1e4feef2f0e176a1ce79e31b00)
created_at: 2025-03-15T00:02:25Z
author_association: COLLABORATOR
diff_hunk: @@ -93,6 +93,20 @@ <h3>Job Listing Form</h3>
         </div> -->
         <h3>Payment Info</h3>
         <div id="card-container"></div>
+        <div class="checkbox-container">
+          <input type="checkbox" id="code-of-conduct-checkbox">
+          <label for="code-of-conduct-checkbox">
+            You agree to 
+            <a id="code-of-conduct-checkbox-link" href="{{ url_for('render_conduct_page') }}"
+              title="Code of Conduct"
+              target="_blank"
+              rel="noopener noreferrer"
+              >
+              Techtonica's Code of Conduct
+            </a>
+            by submitting this form.
+          </label>
+        </div>
         <button id="card-button" type="button" class="sponsor">
path: templates/job-form.html
user: login: daaimah123
body: Validation will be handled with [Payment Form Doesn't Clear Payment Info After Successful Submission](https://github.com/Techtonica/techtonica.org/issues/633#top)
created_at: 2025-03-15T00:09:34Z
author_association: COLLABORATOR
diff_hunk: @@ -94,4 +97,14 @@ window.sendSlackNotification = async function() {
   }
 }
 
+// code of conduct checkbox functionality
+document.addEventListener("DOMContentLoaded", () => {
+  const termsCheckbox = document.getElementById("code-of-conduct-checkbox")
+  const cardButton = document.getElementById("card-button")
+
+  termsCheckbox.addEventListener("change", function () {
+    cardButton.disabled = !this.checked
+  })
+})
path: static/js/payment-flow.js
user: login: monikkaelyse
body: This code to disable the submit button does not seem to be working for me... I'm still able to click the button, and it goes through (with only putting in credit card info. I'm also able to click it multiple times. The first time said "Payment Successful!" The second is the error below.

Note: I believe this code should be removed when the validation code is fixed, and the checkbox is set to required.

![image](https://github.com/user-attachments/assets/e4108837-6553-4207-8acc-0ec85b104e52)

created_at: 2025-03-15T21:27:17Z
author_association: COLLABORATOR
diff_hunk: @@ -94,4 +97,14 @@ window.sendSlackNotification = async function() {
   }
 }
 
+// code of conduct checkbox functionality
+document.addEventListener("DOMContentLoaded", () => {
+  const termsCheckbox = document.getElementById("code-of-conduct-checkbox")
+  const cardButton = document.getElementById("card-button")
+
+  termsCheckbox.addEventListener("change", function () {
+    cardButton.disabled = !this.checked
+  })
+})
path: static/js/payment-flow.js
user: login: daaimah123
body: Addressed in [a43efef](https://github.com/Techtonica/techtonica.org/pull/621/commits/a43efef1552bcb6aff8a5d62b00687acafb8fc42)
created_at: 2025-03-20T19:58:06Z
author_association: COLLABORATOR
diff_hunk: @@ -93,6 +93,20 @@ <h3>Job Listing Form</h3>
         </div> -->
         <h3>Payment Info</h3>
         <div id="card-container"></div>
+        <div class="checkbox-container">
+          <input type="checkbox" id="code-of-conduct-checkbox">
+          <label for="code-of-conduct-checkbox">
+            You agree to 
+            <a id="code-of-conduct-checkbox-link" href="{{ url_for('render_conduct_page') }}"
+              title="Code of Conduct"
+              target="_blank"
+              rel="noopener noreferrer"
+              >
+              Techtonica's Code of Conduct
+            </a>
+            by submitting this form.
+          </label>
+        </div>
         <button id="card-button" type="button" class="sponsor">
path: templates/job-form.html
user: login: daaimah123
body: Addressed in [a43efef](https://github.com/Techtonica/techtonica.org/pull/621/commits/a43efef1552bcb6aff8a5d62b00687acafb8fc42)
created_at: 2025-03-20T19:58:33Z
author_association: COLLABORATOR
diff_hunk: @@ -93,6 +93,20 @@ <h3>Job Listing Form</h3>
         </div> -->
         <h3>Payment Info</h3>
         <div id="card-container"></div>
+        <div class="checkbox-container">
+          <input type="checkbox" id="code-of-conduct-checkbox">
path: templates/job-form.html
user: login: daaimah123
body: Addressed in [a43efef](https://github.com/Techtonica/techtonica.org/pull/621/commits/a43efef1552bcb6aff8a5d62b00687acafb8fc42)
created_at: 2025-03-20T20:00:42Z
author_association: COLLABORATOR

PR comments:
user: login: MichelleGlauser
created_at: 2025-02-28T17:03:21Z
body: Let's change that text to "You agree that what you are submitting in this form agrees to Techtonica's Code of Conduct." 
author_association: MEMBER
user: login: monikkaelyse
created_at: 2025-03-03T19:24:00Z
body: Once changes are in, I will review!
author_association: COLLABORATOR
user: login: daaimah123
created_at: 2025-03-03T23:15:44Z
body: @kaylahrose Addressed (most-all of) your comments in [00bfa38](https://github.com/Techtonica/techtonica.org/pull/621/commits/00bfa38f72a2515b1d26ddd61fae60f67a722e94), [e570ac6](https://github.com/Techtonica/techtonica.org/pull/621/commits/e570ac6854294108c11e41f8eda5c4aff876e5fc), [9ee884c](https://github.com/Techtonica/techtonica.org/pull/621/commits/9ee884c0a60dbe55cac2393bb138678103002927), and [7107bbf](https://github.com/Techtonica/techtonica.org/pull/621/commits/7107bbf32e9d37826f842adc77a7b9599a7ae1cb)
- Can you share what you would like to see for accessibility of the checkbox? 
- Alternatively my styling, removing the underline and changing the text to blue doesn't seem to be working beyond adding an additional class; do you all see what I'm doing wrong?

I have NOT addressed any form validation yet.

<img width="1074" alt="Screenshot 2025-03-03 at 3 24 58 PM" src="https://github.com/user-attachments/assets/1507f22e-a8ad-4b85-a597-59e8c72a33b0" />
<img width="487" alt="Screenshot 2025-03-03 at 3 24 49 PM" src="https://github.com/user-attachments/assets/356947a1-7765-4838-a209-3b484c2abe08" />



author_association: COLLABORATOR
user: login: monikkaelyse
created_at: 2025-03-09T23:02:04Z
body: > * Can you share what you would like to see for accessibility of the checkbox?
> * Alternatively my styling, removing the underline and changing the text to blue doesn't seem to be working beyond adding an additional class; do you all see what I'm doing wrong?
> 

It looks like this page was given the "blue-background" class, which shouldn't really apply in this case since it's not really a full blue background. Since that's being applied, the links for the blue-background (blue-background a) are applying, which makes the check box text white.

I would remove the "class='blue-background'" on #payment-page and then add this in the css

```
#payment-page {
    background-color: #0093b5;
}
```
Seems to resolve it locally for me
author_association: COLLABORATOR
user: login: daaimah123
created_at: 2025-03-15T00:09:52Z
body: This issue creates and styles the code of conduct checkbox. I've identified the validation should be handled with [Payment Form Doesn't Clear Payment Info After Successful Submission](https://github.com/Techtonica/techtonica.org/issues/633#top)
author_association: COLLABORATOR
user: login: daaimah123
created_at: 2025-03-20T19:57:36Z
body: Addressed validation and related styling concerns
![post a job](https://github.com/user-attachments/assets/0134ed80-3660-4182-ae7a-5b43b3775391)

author_association: COLLABORATOR
user: login: MichelleGlauser
created_at: 2025-03-20T20:27:34Z
body: I'm not sure why I said "agrees to." I think I meant, "adheres to." So overall, could you please change the text to be: "By checking this box, you agree that what you are submitting in this form adheres to Techtonica's Code of Conduct"? 
author_association: MEMBER
user: login: daaimah123
created_at: 2025-03-20T22:53:39Z
body: @monikkaelyse and @MichelleGlauser, addressed in [11ccbb2](https://github.com/Techtonica/techtonica.org/pull/621/commits/11ccbb2e2a782aeaa3bdf1b00d47dcf700e2a206)

![post a job successful submission](https://github.com/user-attachments/assets/d8a9e60e-4e62-4cf0-b252-8ae2bac574bf)

author_association: COLLABORATOR
user: login: daaimah123
created_at: 2025-03-22T00:52:09Z
body: Handled blocking "Processing payment information" until the CC is entered. I have not addressed false positives with the profanity checking, @monikkaelyse.

![post a job](https://github.com/user-attachments/assets/280151aa-0c1c-471f-84b5-dcc5d8ed8d45)

author_association: COLLABORATOR