Skip to content

Commit

Permalink
Migrate about to app router
Browse files Browse the repository at this point in the history
- Reorganize files
- Call the flask backend from server side to show external spans
- Remove unused code
  • Loading branch information
lukemun committed Nov 1, 2024
1 parent 91fc877 commit b4aa2a9
Show file tree
Hide file tree
Showing 47 changed files with 230 additions and 705 deletions.
74 changes: 55 additions & 19 deletions next/lib/data.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,10 @@
import { PrismaClient } from '@prisma/client';
import { determineBackendUrl } from '@/src/utils/backendrouter';
import { isOddReleaseWeek, busy_sleep } from '@/src/utils/time';
import * as Sentry from '@sentry/nextjs';

const prisma = new PrismaClient();

// export type Product = {
// id: number;
// description: string;
// descriptionfull: string;
// price: number;
// img: string;
// imgcropped: string;
// reviews: Review[] | [];
// }

// export type Review = {
// id: number;
// productid: number;
// rating: number;
// customerid: string;
// description: string;
// created: string;
// }


export default async function getProducts() {
try {
Expand Down Expand Up @@ -67,3 +51,55 @@ export async function getProduct(index) {
}
}


export async function getOrganization() {
if (Math.random() < 0.01) {
getProducts();
}
return "server /organization"
}



export async function getAbout(backend) {


if (!isOddReleaseWeek()) {
// can't have async sleep in a constructor
busy_sleep(Math.random(25) + 100);
}

const url = determineBackendUrl(backend);
// Http requests to make in parallel, so the Transaction has more Spans
let request1 = fetch(url + '/api', {
method: 'GET',
});
let request2 = fetch(url + '/organization', {
method: 'GET',
});
let request3 = fetch(url + '/connect', {
method: 'GET',
});

// Need Safari13 in tests/config.py in order for this modern javascript to work in Safari Browser
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled#browser_compatibility
// let response = await Promise.allSettled([request1, request2, request3])

const [response1, response2, response3] = await Promise.all([request1, request2, request3]);

console.log([response1, response2, response3]);
const responses = [response1, response2, response3];
// Error Handling
responses.forEach((r) => {
if (!r.ok) {
Sentry.withScope((scope) => {
scope.setContext('response', r);
Sentry.captureException(
new Error(
r.status + ' - ' + (r.statusText || 'Server Error for API')
)
);
});
}
});
}
5 changes: 0 additions & 5 deletions next/next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@ import { withSentryConfig } from '@sentry/nextjs';
/** @type {import('next').NextConfig} */
const nextConfig = {
distDir: './dist', // Changes the build output directory to `./dist/`.
// This should be removed during a refactor, following these directions:
// https://nextjs.org/docs/messages/missing-suspense-with-csr-bailout
experimental: {
missingSuspenseWithCSRBailout: false,
},
};

export default withSentryConfig(nextConfig, {
Expand Down
3 changes: 2 additions & 1 deletion next/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
"react-scripts": "~5.0.1",
"redux": "~4.1.0",
"redux-logger": "~3.0.6",
"web-vitals": "~1.0.1"
"web-vitals": "~1.0.1",
"dompurify": "^3.1.7"
},
"scripts": {
"dev": "next dev",
Expand Down
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import img from '../../assets/emma-garcia.jpg';
import img from '@/public/assets/emma-garcia.jpg';

const Emma = {
name: 'Emma Garcia',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import img from '../../assets/jane-schmidt.jpg';
import img from '@/public/assets/jane-schmidt.jpg';

const Jane = {
name: 'Jane Schmidt',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import img from '../../assets/keith-ryan.jpg';
import img from '@/public/assets/keith-ryan.jpg';

const Keith = {
name: 'Keith Ryan',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import img from '../../assets/lily-chan.jpg';
import img from '@/public/assets/lily-chan.jpg';

const Lily = {
name: 'Lily Chan',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import img from '../../assets/mason-kim.jpg';
import img from '@/public/assets/mason-kim.jpg';

const Mason = {
name: 'Mason Kim',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import img from '../../assets/noah-miller.jpg';
import img from '@/public/assets/noah-miller.jpg';

const Noah = {
name: 'Noah Miller',
Expand Down
64 changes: 13 additions & 51 deletions next/src/app/about/page.jsx
Original file line number Diff line number Diff line change
@@ -1,59 +1,21 @@
'use client'

import Link from 'next/link';

import slugify from '/src/utils/slugify';
import * as Sentry from '@sentry/nextjs';
import { isOddReleaseWeek, busy_sleep } from '/src/utils/time';
import { useEffect } from 'react';

import Jane from '/src/components/employees/jane';
import Lily from '/src/components/employees/lily';
import Keith from '/src/components/employees/keith';
import Mason from '/src/components/employees/mason';
import Emma from '/src/components/employees/emma';
import Noah from '/src/components/employees/noah';

const employees = [Jane, Lily, Keith, Mason, Emma, Noah];

export default function About({ backend }) {
useEffect(() => {
if (!isOddReleaseWeek()) {
// can't have async sleep in a constructor
busy_sleep(Math.random(25) + 100);
}
import slugify from '@/src/utils/slugify';
import { getAbout } from '@/lib/data';

// Http requests to make in parallel, so the Transaction has more Spans
let request1 = fetch(backend + '/api', {
method: 'GET',
});
let request2 = fetch(backend + '/organization', {
method: 'GET',
});
let request3 = fetch(backend + '/connect', {
method: 'GET',
});
import Jane from '@/public/employees/jane';
import Lily from '@/public/employees/lily';
import Keith from '@/public/employees/keith';
import Mason from '@/public/employees/mason';
import Emma from '@/public/employees/emma';
import Noah from '@/public/employees/noah';

// Need Safari13 in tests/config.py in order for this modern javascript to work in Safari Browser
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled#browser_compatibility
// let response = await Promise.allSettled([request1, request2, request3])

const response = [request1, request2, request3];
const employees = [Jane, Lily, Keith, Mason, Emma, Noah];

// Error Handling
response.forEach((r) => {
if (!r.ok) {
Sentry.withScope((scope) => {
scope.setContext('response', r);
Sentry.captureException(
new Error(
r.status + ' - ' + (response.statusText || 'Server Error for API')
)
);
});
}
});
}, []);
export default function About() {
// API calls to flask from server component to show more spans
getAbout('flask');

return (
<div className="about-page">
Expand Down Expand Up @@ -86,7 +48,7 @@ export default function About({ backend }) {
return (
<li key={employee.name}>
<Link href={`/employee/${slugify(employee.url)}`}>
<img src={employee.img} alt={`${employee.name}`} />
<img src={employee.img.src} alt={`${employee.name}`} />
<h5 className="employee-name" name={employee.name}>
{employee.name}
</h5>
Expand Down
2 changes: 1 addition & 1 deletion next/src/app/checkout/page.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ function Checkout({ cart }) {
setLoading(false);

if (hadError) {
router.push('/completeError');
router.push('/complete/error');
} else {
router.push('/complete');
}
Expand Down
38 changes: 38 additions & 0 deletions next/src/app/complete/error/page.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
'use client'

import Link from 'next/link';
import * as Sentry from '@sentry/nextjs';
import { useEffect } from 'react';

function CompleteError() {
useEffect(() => {
window.setTimeout(() => {
if (sessionStorage.getItem('userFeedback') === 'true') {
sessionStorage.removeItem('userFeedback');
if (sessionStorage.getItem('lastErrorEventId')) {
Sentry.showReportDialog({
eventId: sessionStorage.getItem('lastErrorEventId'),
});
} else {
console.log(
'No error event id found, not showing User Feedback report dialog'
);
}
}
}, 3500);
});

return (
<div className="checkout-container-complete sentry-unmask">
<h2>We're having some trouble</h2>
<p>
We were unable to process your order but will do everything we can to
make it right. Please <Link href="#">reach out to us</Link> if you have
been charged or have any questions.
</p>
<button id="contact-us">Contact Us</button>
</div>
);
}

export default CompleteError;
28 changes: 28 additions & 0 deletions next/src/app/complete/page.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
'use client'

import Link from 'next/link';
import { useSelector } from 'react-redux';

function Complete(props) {
const cart = useSelector((state) => state.cart);

const RandomNumber = Math.floor(Math.random() * 99999) + 10000;

return (
<div className="checkout-container-complete">
<h2>Checkout complete</h2>
<h4>
Order No: {RandomNumber} — Total: ${cart.total}.00
</h4>
<p>A confirmation email has been sent to the address you provided.</p>
<p>
Your plants will thank you. You can{' '}
<Link href="/">track your order</Link> or{' '}
<Link href="/">contact us</Link> if you have any questions. Have a sunny
day.
</p>
</div>
);
}

export default Complete;
36 changes: 36 additions & 0 deletions next/src/app/employee/page.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
'use client'
import React, { useEffect, useState } from 'react';
import Link from 'next/link';
// import { useParams } from 'react-router-dom';

function Employee() {
const [employee, setEmployee] = useState();
// TODO this wont work with next routing
// const { id } = useParams();

// useEffect(() => {
// const fetchData = async () => {
// const promise = await import(`@/src/components/employees/${id}`);
// setEmployee(promise.default);
// };

// fetchData();
// }, [employee, id]);

return employee ? (
<div className="employee-page">
<div className="employee-image">
<img src={employee.img} alt={employee.name} />
</div>
<div className="employee-info">
<Link href="/about">Back</Link>
<h1>{employee.name}</h1>
<p>{employee.bio}</p>
</div>
</div>
) : (
<p>Loading…</p>
);
}

export default Employee;
4 changes: 2 additions & 2 deletions next/src/app/layout.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import React from 'react';

import { Suspense } from 'react';

import SentryQueryInitializer from '/src/ui/SentryQueryInitializer';
import HomeContent from '/src/ui/HomeContent';
import SentryQueryInitializer from '@/src/components/SentryQueryInitializer';
import HomeContent from '@/src/ui/HomeContent';

export default function RootLayout({
// Layouts must accept a children prop.
Expand Down
5 changes: 3 additions & 2 deletions next/src/app/product/page.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
import React, { useState, useEffect } from 'react';
import { useRouter } from 'next/router';
import { connect } from 'react-redux';
import { addProduct } from '../actions';
import { addProduct } from '@/src/actions';
import DOMPurify from 'dompurify';

function Product(props) {
const [product, setProduct] = useState();
Expand All @@ -28,7 +29,7 @@ function Product(props) {
return product ? (
<div className="product-layout">
<div>
<img src={product.imgcropped} alt="product" />
<img src={DOMPurify.sanitize(product.imgcropped)} alt="product" />

Check warning

Code scanning / CodeQL

Client-side URL redirect Medium

Untrusted URL redirection depends on a
user-provided value
.
</div>
<div className="product-info">
<h1>{product.title}</h1>
Expand Down
15 changes: 0 additions & 15 deletions next/src/app/products-sc/page.jsx

This file was deleted.

Loading

0 comments on commit b4aa2a9

Please sign in to comment.