Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 7 additions & 33 deletions app/applications/[uuid]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -136,20 +136,15 @@ export default function ApplicationDetailPage({ params }: any) {
};

return (
<div className="min-h-screen p-8" style={{
backgroundColor: 'var(--stanford-white)',
fontFamily: 'Source Sans Pro, Arial, sans-serif',
color: 'var(--stanford-black)',
}}>
<div className="min-h-screen p-8">
<h1 className="text-2xl font-bold mb-6">
Views and Visits Data for {appName ? appName : <span className="font-mono">{typedParams.uuid}</span>}
</h1>
<section className="mb-8 max-w-xl mx-auto bg-white rounded-lg shadow-md p-6 border-2" style={{ borderColor: 'var(--stanford-cardinal)' }}>
<section className="mb-8 max-w-xl mx-auto bg-white rounded-lg p-6 border-2">
<form>
<label
htmlFor="subscriptionUuid"
className="block font-semibold mb-2"
style={{ color: 'var(--stanford-cardinal)' }}
>
Subscription UUID
</label>
Expand All @@ -159,16 +154,11 @@ export default function ApplicationDetailPage({ params }: any) {
value={subscriptionUuid}
onChange={e => setSubscriptionUuid(e.target.value)}
className="w-full p-2 border rounded mb-4"
style={{
borderColor: 'var(--stanford-gray)',
color: 'var(--stanford-black)',
fontFamily: 'Source Sans Pro, Arial, sans-serif',
}}
required
/>
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 mb-4">
<div>
<label htmlFor="dateFrom" className="block text-sm font-medium mb-2" style={{ color: 'var(--stanford-cardinal)' }}>
<label htmlFor="dateFrom" className="block text-sm font-medium mb-2">
From Date
</label>
<input
Expand All @@ -177,16 +167,11 @@ export default function ApplicationDetailPage({ params }: any) {
value={from}
onChange={(e) => setFrom(e.target.value)}
className="w-full px-3 py-2 border rounded-md focus:outline-none"
style={{
borderColor: 'var(--stanford-gray)',
color: 'var(--stanford-black)',
fontFamily: 'Source Sans Pro, Arial, sans-serif',
}}
disabled={loading}
/>
</div>
<div>
<label htmlFor="dateTo" className="block text-sm font-medium mb-2" style={{ color: 'var(--stanford-cardinal)' }}>
<label htmlFor="dateTo" className="block text-sm font-medium mb-2">
To Date
</label>
<input
Expand All @@ -195,11 +180,6 @@ export default function ApplicationDetailPage({ params }: any) {
value={to}
onChange={(e) => setTo(e.target.value)}
className="w-full px-3 py-2 border rounded-md focus:outline-none"
style={{
borderColor: 'var(--stanford-gray)',
color: 'var(--stanford-black)',
fontFamily: 'Source Sans Pro, Arial, sans-serif',
}}
disabled={loading}
/>
</div>
Expand All @@ -211,33 +191,27 @@ export default function ApplicationDetailPage({ params }: any) {
onClick={fetchAppDetail}
disabled={loading || !subscriptionUuid}
className="px-6 py-2 rounded-md font-semibold transition-colors duration-150"
style={{
backgroundColor: 'var(--stanford-cardinal)',
color: 'var(--stanford-white)',
border: '2px solid var(--stanford-cardinal)',
fontFamily: 'Source Sans Pro, Arial, sans-serif',
}}
>
{loading ? 'Fetching Data...' : 'Fetch Analytics Data'}
</button>
{loading && (
<div className="flex items-center space-x-3">
<CountUpTimer isRunning={loading} />
<div className="font-medium" style={{ color: 'var(--stanford-cardinal)' }}>{loadingStep}</div>
<div className="font-medium">{loadingStep}</div>
</div>
)}

{!loading && elapsedTime !== null && (
<div className="flex items-center space-x-3">
<CountUpTimer isRunning={false} finalTime={elapsedTime} />
<div className="font-medium" style={{ color: 'var(--stanford-gold)' }}>
<div className="font-medium">
Data loaded in {elapsedTime.toFixed(1)} seconds
</div>
</div>
)}
</div>

<p className="mt-2 text-sm" style={{ color: 'var(--stanford-gray)' }}>
<p className="mt-2 text-sm">
(Note that it can take several minutes to fetch data from the Acquia API.)
</p>
</form>
Expand Down
3 changes: 1 addition & 2 deletions app/applications/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ async function fetchData() {
viewsRes.ok ? viewsRes.json() : [],
visitsRes.ok ? visitsRes.json() : [],
]);
// console.log('viewsRaw:', viewsRaw);
// console.log('visitsRaw:', visitsRaw);

// Defensive: ensure arrays
const views = Array.isArray(viewsRaw)
? viewsRaw
Expand Down
65 changes: 18 additions & 47 deletions app/globals.css
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
/* Add this to your CSS */
.recharts-wrapper, .recharts-surface {
width: 100% !important;
height: 100% !important;
@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";

/* Stanford Font */
html {
font-size: 100%;
}

.recharts-wrapper {
width: 90% !important;
margin: 0 auto;
}

.recharts-tooltip-label,
.recharts-tooltip-item-list {
font-size: 18px;
}

.w-full {
Expand Down Expand Up @@ -32,46 +45,4 @@
width: 100%;
height: 400px;
min-height: 400px;
}

/* Stanford Brand Colors */
:root {
--stanford-cardinal: #8C1515;
--stanford-black: #2B2D2F;
--stanford-gray: #4D4F53;
--stanford-white: #FFFFFF;
--stanford-gold: #B83A4B;
}

/* Stanford Font */
body {
font-family: 'Source Sans Pro', Arial, sans-serif;
background-color: var(--stanford-white);
color: var(--stanford-black);
}

/* Table Styling */
.stanford-table {
border: 2px solid var(--stanford-cardinal);
border-radius: 0.5rem;
background-color: var(--stanford-white);
box-shadow: 0 4px 6px -1px rgba(44, 21, 21, 0.1), 0 2px 4px -1px rgba(44, 21, 21, 0.06);
}

.stanford-table th {
background-color: var(--stanford-cardinal);
color: var(--stanford-white);
font-weight: bold;
text-transform: uppercase;
}

.stanford-table td {
border: 1px solid var(--stanford-gray);
color: var(--stanford-black);
}

.stanford-table tfoot td {
background-color: var(--stanford-gray);
color: var(--stanford-white);
font-weight: bold;
}
}
111 changes: 105 additions & 6 deletions app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,121 @@
import './globals.css';
import type { Metadata } from 'next';
import { Inter } from 'next/font/google';
import { Source_Sans_3, Source_Serif_4 } from 'next/font/google';
import localFont from 'next/font/local';
import { GlobalFooter } from '@/components/GlobalFooter/GlobalFooter';
import { cnb } from 'cnbuilder';

const inter = Inter({ subsets: ['latin'] });
const source_sans = Source_Sans_3({
subsets: ['latin'],
style: ['italic','normal'],
display: 'swap',
variable: '--font-source-sans',
});

const source_serif = Source_Serif_4({
subsets: ['latin'],
style: ['italic','normal'],
display: 'swap',
variable: '--font-source-serif',
});

const stanford = localFont({
src: '../public/fonts/stanford.woff2',
weight: '300',
variable: '--font-stanford',
});

export const metadata: Metadata = {
title: 'Acquia API Dashboard',
description: 'Dashboard for visualizing Acquia API data',
title: 'CHURRO',
description: 'Dashboard for Acquia Views/Visits data',
applicationName: 'Stanford University',
icons: {
icon: [
{ url: '/favicon.ico', type: 'image/vnd.microsoft.icon' },
{ url: 'https://www-media.stanford.edu/assets/favicon/favicon-196x196.png', sizes: '196x196', type: 'image/png' },
{ url: 'https://www-media.stanford.edu/assets/favicon/favicon-192x192.png', sizes: '192x192', type: 'image/png' },
{ url: 'https://www-media.stanford.edu/assets/favicon/favicon-128.png', sizes: '128x128', type: 'image/png' },
{ url: 'https://www-media.stanford.edu/assets/favicon/favicon-96x96.png', sizes: '96x96', type: 'image/png' },
{ url: 'https://www-media.stanford.edu/assets/favicon/favicon-32x32.png', sizes: '32x32', type: 'image/png' },
{ url: 'https://www-media.stanford.edu/assets/favicon/favicon-16x16.png', sizes: '16x16', type: 'image/png' },
],
apple: [
{ url: 'https://www-media.stanford.edu/assets/favicon/apple-touch-icon-60x60.png', sizes: '60x60' },
{ url: 'https://www-media.stanford.edu/assets/favicon/apple-touch-icon-72x72.png', sizes: '72x72' },
{ url: 'https://www-media.stanford.edu/assets/favicon/apple-touch-icon-76x76.png', sizes: '76x76' },
{ url: 'https://www-media.stanford.edu/assets/favicon/apple-touch-icon-114x114.png', sizes: '114x114' },
{ url: 'https://www-media.stanford.edu/assets/favicon/apple-touch-icon-120x120.png', sizes: '120x120' },
{ url: 'https://www-media.stanford.edu/assets/favicon/apple-touch-icon-144x144.png', sizes: '144x144' },
{ url: 'https://www-media.stanford.edu/assets/favicon/apple-touch-icon-152x152.png', sizes: '152x152' },
{ url: 'https://www-media.stanford.edu/assets/favicon/apple-touch-icon-180x180.png', sizes: '180x180' },
],
other: [
{ rel: 'mask-icon', url: 'https://www-media.stanford.edu/assets/favicon/safari-pinned-tab.svg', color: '#ffffff' },
],
},
other: {
'msapplication-TileColor': '#FFFFFF',
'msapplication-TileImage': 'https://www-media.stanford.edu/assets/favicon/mstile-144x144.png',
'msapplication-square70x70logo': 'https://www-media.stanford.edu/assets/favicon/mstile-70x70.png',
'msapplication-square150x150logo': 'https://www-media.stanford.edu/assets/favicon/mstile-150x150.png',
'msapplication-square310x310logo': 'https://www-media.stanford.edu/assets/favicon/mstile-310x310.png',
},
};

function StanfordHeader() {
return (
<header className="stanford-header">
<div className="px-20 sm:px-30 md:px-50 lg:px-30 pt-5 pb-1 bg-cardinal-red">
<a className="logo hocus:no-underline text-white hocus:text-white text-20 leading-none" href="https://www.stanford.edu">Stanford University</a>
</div>
<div className="flex flex-col md:flex-row items-center px-20 sm:px-30 md:px-50 lg:px-30 py-4">
<div className="rs-p-0">
<a
href="/"
className="logo text-cardinal-red type-3 no-underline hover:no-underline focus:no-underline active:no-underline"
aria-label="Go to CHURRO homepage"
>
<span className="block">
Stanford <br/> University
</span>
</a>
</div>

<div className="ml-4">
<a
href="/"
className="no-underline hover:no-underline focus:no-underline active:no-underline text-black hover:text-black focus:text-black active:text-black"
aria-label="Go to CHURRO homepage"
>
<h1 className="text-4xl rs-p-0 whitespace-nowrap">Cloud Hosting Usage Reporting with Recurring Output (CHURRO)</h1>
</a>
</div>
</div>
</header>
);
}

export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body className={inter.className}>{children}</body>
<html lang="en"
className={cnb(
source_sans.variable,
source_serif.variable,
stanford.variable,
)}>
<body className={cnb(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jbickar I think I would put your favions in a component and then link it here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude said:

In Next.js 13+ with the app directory, you should add metadata directly to the metadata object in layout.tsx` rather than creating a separate head component.

TIL. See commit a32aa1d

source_sans.variable,
source_serif.variable,
stanford.variable,
)}>
<StanfordHeader />
<main>{children}</main>
<GlobalFooter />
</body>
</html>
);
}
12 changes: 12 additions & 0 deletions components/Container/Container.styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export const widths = {
full: 'w-full', // width: 100%; default
site: 'cc', // Use Decanter custom screen margins and sets max content width of 1500px
wide: 'cc 3xl:px-100 4xl:px-[calc((100%-1800px)/2)]',
screen: 'w-screen', // width: 100vw
};

export const bgColors = {
black: 'bg-gc-black text-white',
white: 'bg-white text-gc-black',
'fog-light': 'bg-fog-light text-gc-black',
};
61 changes: 61 additions & 0 deletions components/Container/Container.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { HTMLAttributes } from 'react';
import { cnb } from 'cnbuilder';
import {
paddingTops,
paddingBottoms,
paddingVerticals,
marginTops,
marginBottoms,
marginVerticals,
type MarginType,
type PaddingType,
} from '@/utilities/datasource';
import * as styles from './Container.styles';
import * as types from './Container.types';

export type ContainerProps = HTMLAttributes<HTMLElement> & {
as?: types.ContainerElementType;
width?: types.WidthType;
pt?: PaddingType;
pb?: PaddingType;
py?: PaddingType;
mt?: MarginType;
mb?: MarginType;
my?: MarginType;
bgColor?: types.BgColorType;
style?: React.CSSProperties;
};

export const Container = ({
as: AsComponent = 'div',
width = 'site',
py,
pt,
pb,
mt,
mb,
my,
bgColor,
style,
className,
children,
...props
}: ContainerProps) => (
<AsComponent
{...props}
style={style}
className={cnb(
bgColor ? styles.bgColors[bgColor] : '',
py ? paddingVerticals[py] : '',
pt ? paddingTops[pt] : '',
pb ? paddingBottoms[pb] : '',
my ? marginVerticals[my] : '',
mt ? marginTops[mt] : '',
mb ? marginBottoms[mb] : '',
width ? styles.widths[width] : '',
className,
)}
>
{children}
</AsComponent>
);
Loading