From b4b8eaec38cc837771f1bd9f7edc79ab60000c75 Mon Sep 17 00:00:00 2001 From: dxbenson252 Date: Mon, 6 Oct 2025 18:53:20 +0000 Subject: [PATCH 1/3] Get and post implementations starters --- .../my_template/src/components/Program.tsx | 15 ++ .../src/components/ProgramList.tsx | 26 +++ .../src/components/header/Header.tsx | 35 ++++ .../my_template/src/components/index.ts | 2 + .../src/contexts/ProgramsContext.tsx | 74 ++++++++ .../devynbenson/my_template/src/main.tsx | 39 ++++ .../src/pages/AddProgram/AddProgram.scss | 179 ++++++++++++++++++ .../src/pages/AddProgram/AddProgram.tsx | 126 ++++++++++++ .../my_template/src/pages/Home/Home.scss | 139 ++++++++++++++ .../my_template/src/pages/Home/Home.tsx | 42 ++++ .../lesson23/web/MediaItemsController.java | 66 ++++++- 11 files changed, 739 insertions(+), 4 deletions(-) create mode 100644 lesson_22/devynbenson/my_template/src/components/Program.tsx create mode 100644 lesson_22/devynbenson/my_template/src/components/ProgramList.tsx create mode 100644 lesson_22/devynbenson/my_template/src/components/header/Header.tsx create mode 100644 lesson_22/devynbenson/my_template/src/components/index.ts create mode 100644 lesson_22/devynbenson/my_template/src/contexts/ProgramsContext.tsx create mode 100644 lesson_22/devynbenson/my_template/src/main.tsx create mode 100644 lesson_22/devynbenson/my_template/src/pages/AddProgram/AddProgram.scss create mode 100644 lesson_22/devynbenson/my_template/src/pages/AddProgram/AddProgram.tsx create mode 100644 lesson_22/devynbenson/my_template/src/pages/Home/Home.scss create mode 100644 lesson_22/devynbenson/my_template/src/pages/Home/Home.tsx diff --git a/lesson_22/devynbenson/my_template/src/components/Program.tsx b/lesson_22/devynbenson/my_template/src/components/Program.tsx new file mode 100644 index 000000000..601245a15 --- /dev/null +++ b/lesson_22/devynbenson/my_template/src/components/Program.tsx @@ -0,0 +1,15 @@ +import React from 'react'; + +interface ProgramProps { + title: string; + description: string; +} + +export const Program: React.FC = ({ title, description }) => { + return ( +
  • +

    {title}

    +

    {description}

    +
  • + ); +}; diff --git a/lesson_22/devynbenson/my_template/src/components/ProgramList.tsx b/lesson_22/devynbenson/my_template/src/components/ProgramList.tsx new file mode 100644 index 000000000..72ff46732 --- /dev/null +++ b/lesson_22/devynbenson/my_template/src/components/ProgramList.tsx @@ -0,0 +1,26 @@ +import React from 'react'; +import { Program } from './Program'; +import { Program as ProgramType } from '../contexts/ProgramsContext'; + +interface ProgramListProps { + programs: ProgramType[]; +} + +export const ProgramList: React.FC = ({ programs }) => { + return ( +
    +

    + Our Programs +

    +
      + {programs.map((program) => ( + + ))} +
    +
    + ); +}; diff --git a/lesson_22/devynbenson/my_template/src/components/header/Header.tsx b/lesson_22/devynbenson/my_template/src/components/header/Header.tsx new file mode 100644 index 000000000..dd35951bd --- /dev/null +++ b/lesson_22/devynbenson/my_template/src/components/header/Header.tsx @@ -0,0 +1,35 @@ +import './Header.scss'; +import logoImg from '@/assets/logo.png'; +import React from 'react'; +import { Link } from 'react-router-dom'; + +export const Header: React.FC = () => { + return ( +
    +
    + + Code Differently Logo + +
    + +
    + + Add Program + +
    +
    + ); +}; diff --git a/lesson_22/devynbenson/my_template/src/components/index.ts b/lesson_22/devynbenson/my_template/src/components/index.ts new file mode 100644 index 000000000..b5e117ff5 --- /dev/null +++ b/lesson_22/devynbenson/my_template/src/components/index.ts @@ -0,0 +1,2 @@ +export { Program } from './Program'; +export { ProgramList } from './ProgramList'; diff --git a/lesson_22/devynbenson/my_template/src/contexts/ProgramsContext.tsx b/lesson_22/devynbenson/my_template/src/contexts/ProgramsContext.tsx new file mode 100644 index 000000000..5d0eb837d --- /dev/null +++ b/lesson_22/devynbenson/my_template/src/contexts/ProgramsContext.tsx @@ -0,0 +1,74 @@ +import React, { createContext, useContext, useState, ReactNode } from 'react'; + +export interface Program { + id: string; + title: string; + description: string; + dateAdded: Date; +} + +interface ProgramsContextType { + programs: Program[]; + addProgram: (title: string, description: string) => void; +} + +const ProgramsContext = createContext(undefined); + +interface ProgramsProviderProps { + children: ReactNode; +} + +export const ProgramsProvider: React.FC = ({ children }) => { + // Initial programs data + const [programs, setPrograms] = useState([ + { + id: '1', + title: "1000 Kids Coding", + description: "The Code Differently 1000 Kids Coding program was created to expose New Castle County students to computing and programming. The 1000 Kids Coding courses are designed for all experience levels, no experience required.", + dateAdded: new Date('2024-01-01') + }, + { + id: '2', + title: "Return Ready", + description: "The Code Differently Workforce Training Initiatives were created to help individuals underrepresented in tech reinvent their skills to align with the changing workforce market. If you are ready to start your tech journey, join our talent community today.", + dateAdded: new Date('2024-02-01') + }, + { + id: '3', + title: "Pipeline DevShops", + description: "Pipeline DevShop is a youth work-based learning program. Youth participants experience working in a real software development environment while sharpening their technology and soft skills.", + dateAdded: new Date('2024-03-01') + }, + { + id: '4', + title: "Platform Programs", + description: "Platform programs are designed for high school graduates, college students, career changers, or professionals looking to develop the technology job readiness skills for today's workforce.", + dateAdded: new Date('2024-04-01') + } + ]); + + const addProgram = (title: string, description: string) => { + const newProgram: Program = { + id: Date.now().toString(), // Simple ID generation + title, + description, + dateAdded: new Date() + }; + + setPrograms(prevPrograms => [...prevPrograms, newProgram]); + }; + + return ( + + {children} + + ); +}; + +export const usePrograms = () => { + const context = useContext(ProgramsContext); + if (context === undefined) { + throw new Error('usePrograms must be used within a ProgramsProvider'); + } + return context; +}; diff --git a/lesson_22/devynbenson/my_template/src/main.tsx b/lesson_22/devynbenson/my_template/src/main.tsx new file mode 100644 index 000000000..abf00dad0 --- /dev/null +++ b/lesson_22/devynbenson/my_template/src/main.tsx @@ -0,0 +1,39 @@ +import App from './App.tsx'; +import {Home} from './pages/Home/Home.tsx'; +import {AddProgram} from './pages/AddProgram/AddProgram.tsx'; +import {ProgramsProvider} from './contexts/ProgramsContext.tsx'; +import {QueryClient, QueryClientProvider} from '@tanstack/react-query'; +import React from 'react'; +import ReactDOM from 'react-dom/client'; +import {RouterProvider, createBrowserRouter} from 'react-router-dom'; + +import './index.scss'; + +const queryClient = new QueryClient(); + +const router = createBrowserRouter([ + { + path: '/', + element: , + children: [ + { + path: '/', + element: , + }, + { + path: '/add-program', + element: , + }, + ], + }, +]); + +ReactDOM.createRoot(document.getElementById('root')!).render( + + + + + + + +); diff --git a/lesson_22/devynbenson/my_template/src/pages/AddProgram/AddProgram.scss b/lesson_22/devynbenson/my_template/src/pages/AddProgram/AddProgram.scss new file mode 100644 index 000000000..deddc985a --- /dev/null +++ b/lesson_22/devynbenson/my_template/src/pages/AddProgram/AddProgram.scss @@ -0,0 +1,179 @@ +.add-program-section { + padding: 60px 20px; + background-color: #f5f5f5; + min-height: 70vh; + display: flex; + justify-content: center; + align-items: center; +} + +.add-program-container { + max-width: 600px; + width: 100%; + background: white; + border-radius: 12px; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); + padding: 40px; +} + +.add-program-title { + font-size: 2.5em; + font-weight: 700; + text-align: center; + margin-bottom: 10px; + color: #333; + + .highlight { + color: #243e90; + font-style: normal; + } +} + +.add-program-subtitle { + text-align: center; + color: #666; + margin-bottom: 30px; + font-size: 1.1em; + line-height: 1.5; +} + +.add-program-form { + display: flex; + flex-direction: column; + gap: 25px; +} + +.form-group { + display: flex; + flex-direction: column; +} + +.form-label { + font-weight: 600; + margin-bottom: 8px; + color: #333; + font-size: 1em; +} + +.form-input, +.form-textarea { + padding: 12px 16px; + border: 2px solid #e1e5e9; + border-radius: 8px; + font-size: 1em; + font-family: inherit; + transition: all 0.3s ease; + background-color: #fafafa; + + &:focus { + outline: none; + border-color: #243e90; + background-color: white; + box-shadow: 0 0 0 3px rgba(36, 62, 144, 0.1); + } + + &::placeholder { + color: #999; + } +} + +.form-textarea { + resize: vertical; + min-height: 120px; + line-height: 1.5; +} + +.form-actions { + display: flex; + gap: 15px; + margin-top: 10px; + + @media screen and (max-width: 480px) { + flex-direction: column; + } +} + +.btn { + padding: 12px 24px; + border: none; + border-radius: 8px; + font-size: 1em; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + text-decoration: none; + display: inline-flex; + align-items: center; + justify-content: center; + min-height: 48px; + + &:disabled { + opacity: 0.6; + cursor: not-allowed; + transform: none !important; + } + + &:not(:disabled):hover { + transform: translateY(-2px); + } +} + +.btn-primary { + background-color: #243e90; + color: white; + flex: 1; + + &:not(:disabled):hover { + background-color: #1a2d6b; + box-shadow: 0 4px 12px rgba(36, 62, 144, 0.3); + } +} + +.btn-secondary { + background-color: transparent; + color: #666; + border: 2px solid #e1e5e9; + + &:not(:disabled):hover { + background-color: #f8f9fa; + border-color: #ccc; + } +} + +.message { + padding: 12px 16px; + border-radius: 8px; + margin-bottom: 20px; + font-weight: 500; + text-align: center; + + &.success { + background-color: #d4edda; + border: 1px solid #c3e6cb; + color: #155724; + } + + &.error { + background-color: #f8d7da; + border: 1px solid #f5c6cb; + color: #721c24; + } +} + +@media screen and (max-width: 768px) { + .add-program-section { + padding: 40px 15px; + } + + .add-program-container { + padding: 30px 20px; + } + + .add-program-title { + font-size: 2em; + } + + .add-program-subtitle { + font-size: 1em; + } +} diff --git a/lesson_22/devynbenson/my_template/src/pages/AddProgram/AddProgram.tsx b/lesson_22/devynbenson/my_template/src/pages/AddProgram/AddProgram.tsx new file mode 100644 index 000000000..00167d5b2 --- /dev/null +++ b/lesson_22/devynbenson/my_template/src/pages/AddProgram/AddProgram.tsx @@ -0,0 +1,126 @@ +import './AddProgram.scss'; +import React, { useState } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { usePrograms } from '../../contexts/ProgramsContext'; + +export const AddProgram: React.FC = () => { + const navigate = useNavigate(); + const { addProgram } = usePrograms(); + const [formData, setFormData] = useState({ + title: '', + description: '' + }); + const [isSubmitting, setIsSubmitting] = useState(false); + const [message, setMessage] = useState(''); + + const handleInputChange = (e: React.ChangeEvent) => { + const { name, value } = e.target; + setFormData(prev => ({ + ...prev, + [name]: value + })); + }; + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + setIsSubmitting(true); + setMessage(''); + + try { + // Simulate form submission (in a real app, this would be an API call) + await new Promise(resolve => setTimeout(resolve, 1000)); + + // Add the program to the global state + addProgram(formData.title, formData.description); + + console.log('Program submitted:', formData); + setMessage(`Successfully added program: "${formData.title}"`); + + // Reset form + setFormData({ title: '', description: '' }); + + // Navigate back to home after a delay to show the new program + setTimeout(() => { + navigate('/'); + }, 2000); + + } catch (error) { + setMessage('Error submitting program. Please try again.'); + } finally { + setIsSubmitting(false); + } + }; + + return ( +
    +
    +
    +

    + Add New Program +

    +

    + Help us expand our offerings by adding a new program to Code Differently. +

    + + {message && ( +
    + {message} +
    + )} + +
    +
    + + +
    + +
    + +