diff --git a/ProjectOrientedSessions/Session05/React/Mosh React.md b/ProjectOrientedSessions/Session05/React/Mosh React.md deleted file mode 100644 index 12a60f2..0000000 --- a/ProjectOrientedSessions/Session05/React/Mosh React.md +++ /dev/null @@ -1 +0,0 @@ -- [ ] Watch https://www.youtube.com/watch?v=SqcY0GlETPk&ab_channel=ProgrammingwithMosh \ No newline at end of file diff --git a/ProjectOrientedSessions/Session05/Session05 Additional Info.md b/ProjectOrientedSessions/Session05/Session05 Additional Info.md index e69de29..1b35798 100644 --- a/ProjectOrientedSessions/Session05/Session05 Additional Info.md +++ b/ProjectOrientedSessions/Session05/Session05 Additional Info.md @@ -0,0 +1,436 @@ + +## What is CORS? (Chat GPT) +### CORS (Cross-Origin Resource Sharing) + +**What it is:** CORS is a browser security feature that blocks requests to a different domain unless explicitly allowed by the server. +### 🔐 What is CORS **really** for? + +CORS is **not** about protecting the backend server. +It’s about **protecting users** from **malicious websites** using their browser as a weapon. + +--- + +### 🧠 Imagine this attack: + +You’re logged into your **bank** in one browser tab (`bank.com`). + +Now, you visit a shady website in another tab (`evil.com`). That site has JavaScript that tries to send this: + +```js +fetch('https://bank.com/api/transfer?amount=5000&to=hacker', { + credentials: 'include' // it sends your bank cookies! +}); +``` + +➡️ If the browser allowed this freely, the request would go through **using your login session**, and you’d lose money. + +--- + +### 💥 Enter CORS + +So the browser says: + +> “Hold on. This JavaScript is from `evil.com`, and it’s trying to talk to `bank.com`. I won’t let that happen **unless `bank.com` says it’s okay**.” + +That’s why the **backend server** must respond with something like: + +```http +Access-Control-Allow-Origin: https://mytrusteddomain.com +``` + +Only then will the browser say, “Okay, go ahead.” + +--- + +### So the purpose of CORS is: + +✅ To **restrict browsers** from sending or accepting responses from **cross-origin** sources +❌ Not to protect the backend +❌ Not to restrict Postman, curl, servers, or mobile apps + +--- + +### 🔄 In Dev Work (like your React + API case): + +- You’re running React at `http://localhost:5173` +- You’re running ASP.NET Core API at `https://localhost:7001` +- The browser sees this as two **different origins** → blocks the request unless CORS is enabled on the API. + +--- + +### 🧪 Why Postman works: +- Postman isn’t a browser +- Postman doesn’t care about same-origin policy +- Postman just sends requests like your backend would + +--- + +### ✅ Conclusion: + +- **CORS is a browser feature to protect users** +- **It restricts frontend JavaScript from calling other domains unless explicitly allowed** +- **You must configure your server to say “Yes, I allow your frontend to talk to me”** + + +## Feature-based Folder Structure +> +## Explanation of the `agent.ts` +> +## React.FC + +### what is `React.FC`? + +- `React.FC` (or `React.FunctionComponent`) is a **TypeScript type** that you can use to type your functional React components. + +- It **tells TypeScript** that: + - This component is a function + - It **receives props** (in your case, `Props`) + - It **returns JSX** (it returns something React can render) + +--- + +### Why use it? + +Here’s what you get when you use `React.FC`: +1. ✅ **Prop typing** — You get auto-complete and error checking for props. +2. ✅ **Children** are automatically included. (More on this below.) +3. ✅ **Cleaner code** because TypeScript understands the shape of the component. + +--- + +### Without `React.FC` + +You could just write: + +```tsx +const TransportationCard = ({ transportation }: Props) => { ... } +``` +You lose some "extra typing safety" like automatic `children` typing. + +--- + +### Small Detail: `children` + +When you use `React.FC`, **TypeScript automatically** allows your component to accept `children` too — even if you didn’t define it in your `Props`. + +For example: + +```tsx + +

Hello

// This would be valid automatically +
+``` + +Because `children` is **always** part of a `React.FC`. + +👉 If you **don't** use `React.FC`, and you want to accept `children`, you have to **manually** add it to your props. + +--- + +### Some developers today... +**Some people** (even in big companies) prefer **NOT** to use `React.FC` anymore because: +- It **forces children** even when you don’t want children. +- It's **a little bit redundant** — you can already just type props without it. + +> So in modern codebases, **both styles are OK** — it’s just a preference. + +--- + +### Quick Summary: + +| Using `React.FC` | Not using `React.FC` | +| :------------------------------------------- | :---------------------------------------------- | +| Good for simple, typed functional components | Good if you want full manual control over props | +| Auto-includes `children` prop | You must manually add `children` if needed | +| Easy and quick | More customizable | + +--- + +## `CityDropdown` Component: + +### 1. **State Variables** + +```tsx +const [cities, setCities] = useState([]); +const [selectedCity, setSelectedCity] = useState(); +``` + +- `cities`: holds the list of cities retrieved from the backend (starts empty `[]`). +- `selectedCity`: holds the currently selected city’s ID (`number`) or `undefined` if nothing is selected yet. + + +--- + +### 2. **Fetching Cities on Mount** + +```tsx +useEffect(() => { + agent.Cities.list() + .then(setCities) + .catch((err) => console.error("error loading cities", err)); +}, []); +``` + +- When the component **mounts** (`[]` dependency array = run once), it calls `agent.Cities.list()`. +- `agent.Cities.list()` presumably returns a promise that resolves to an array of `City` objects. +- On success → `setCities` updates the `cities` state. +- On failure → logs an error to the console. + +--- + +### 3. **Rendering the Dropdown** + +```tsx + +``` + +- Renders a ` setSelectedCity(Number(e.target.value))} -> - - {cities.map((city) => ( - - ))} - -``` - -- Renders a `` dropdown fills up! - ---- - -#### 3. ✏️ Handle input changes - -```tsx -const handleChange = (e: React.ChangeEvent) => { ... } -``` - -Whenever a user types/selects: - -- You detect **which field** (`name`) and **what value** (`value`) they changed - -- Update the `form` state accordingly: - - `fromCityId` and `toCityId` are converted to numbers (`parseInt`) - - `startDate` and `endDate` allow null - - Other fields (if any) are copied directly - ---- - -#### 4. 🔍 Handle Search button - -```tsx -const handleSearch = () => { ... } -``` - -When the user clicks **Search**: - -- Set `loading` to `true` -- Call the backend API `agent.TransportationSearch.search(form)` -- When the result comes back: - - Save it into `searchResults` -- If error: log it -- Finally, set `loading` to `false` again - ---- - -#### 5. 🖥️ Return (render) JSX -You build a UI: - -- **Vehicle Types** (Bus, Train, Airplane) selectable with a click → sets `vehicleTypeId` -- **From City** and **To City** dropdowns -- **Start and End Date** inputs -- **Search Button** to trigger the search -- **Result area** that shows: - - If loading: "Loading..." - - If no results: "No results found" - - If results: List of `TransportationCard` components for each found item. - - ---- - - - - +# 🧠 Hints & Notes +# 🙌 Acknowledgements +- ChatGPT for snippet refinement and explanations +# 🔍 References +- [ ] Check out [[Session05 Additional Info]] +- [ ] Watch for [React](https://www.youtube.com/watch?v=SqcY0GlETPk&ab_channel=ProgrammingwithMosh)