Skip to content

Commit

Permalink
Merge pull request #7952 from sagemathinc/store-license-3-panels
Browse files Browse the repository at this point in the history
next/store: make all license presets selectable columns
  • Loading branch information
williamstein authored Oct 16, 2024
2 parents 7364593 + 55b47c2 commit 8686af1
Show file tree
Hide file tree
Showing 8 changed files with 360 additions and 170 deletions.
45 changes: 35 additions & 10 deletions src/packages/next/components/landing/pricing-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,44 @@ import { ReactNode } from "react";

import { Icon, IconName } from "@cocalc/frontend/components/icon";
import { COLORS } from "@cocalc/util/theme";
import { CSS } from "components/misc";

import styles from "./pricing.module.css";

interface Props {
children: ReactNode;
icon: IconName;
title: string;
style?: CSS;
active?: boolean;
onClick?: () => void;
}

export default function PricingItem({ icon, children, title }: Props) {
const ACTIVE_STYLE: CSS = {
outline: `2px solid ${COLORS.BLUE_D}`,
} as const;

export default function PricingItem({
icon,
children,
title,
style,
active,
onClick,
}: Props) {
const outerStyle: CSS = {
padding: 0,
...style,
} as const;
const activeStyle: CSS = active === true ? ACTIVE_STYLE : {};
const innerStyle: CSS = { color: COLORS.GRAY_M, ...activeStyle };

return (
<List.Item style={{ padding: 0 }}>
<List.Item style={outerStyle} onClick={onClick}>
<Card
styles={{ header: { backgroundColor: "#d9edf7" } }}
style={{ color: COLORS.GRAY_M }}
className={onClick != null ? styles.item : undefined}
styles={{ header: { backgroundColor: COLORS.BLUE_LLLL } }}
style={innerStyle}
type="inner"
title={
<span style={{ fontSize: "120%" }}>
Expand All @@ -44,10 +69,11 @@ const STYLE: React.CSSProperties = {
interface Line {
amount?: string | number | ReactNode;
desc?: string | ReactNode;
indent?: boolean;
}

export function Line(props: Line) {
const { amount, desc } = props;
const { amount, desc, indent = true } = props;
if (!amount)
return (
<div>
Expand All @@ -67,14 +93,13 @@ export function Line(props: Line) {
unit = "x";
}
}

const indentStyle: CSS = indent ? { width: "3em", textAlign: "right" } : {};

return (
<div>
<b style={STYLE}>
<div
style={{ display: "inline-block", width: "3em", textAlign: "right" }}
>
{amount}
</div>{" "}
<div style={{ display: "inline-block", ...indentStyle }}>{amount}</div>{" "}
{unit}
</b>{" "}
{desc}
Expand Down
10 changes: 10 additions & 0 deletions src/packages/next/components/landing/pricing.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.item {
cursor: pointer;
position: relative;
transition: 0.1s;
top: 0;
}

.item:hover {
top: -5px;
}
99 changes: 89 additions & 10 deletions src/packages/next/components/store/quota-config-presets.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@

import { IconName } from "@cocalc/frontend/components/icon";
import { Uptime } from "@cocalc/util/consts/site-license";
import { Paragraph } from "components/misc";
import A from "components/misc/A";
import { ReactNode } from "react";

export type Presets = "standard" | "instructor" | "research";
export type Preset = "standard" | "instructor" | "research";

// Fields to be used to match a configured license against a pre-existing preset.
//
Expand All @@ -20,32 +21,51 @@ export const PRESET_MATCH_FIELDS: Record<string, string> = {
member: "member hosting",
};

export interface Preset {
icon?: IconName;
export interface PresetConfig {
icon: IconName;
name: string;
descr: ReactNode;
details?: ReactNode;
details: ReactNode;
cpu: number;
ram: number;
disk: number;
uptime: Uptime;
member: boolean;
expect: string[];
note?: ReactNode;
}

type PresetEntries = {
[key in Presets]: Preset;
[key in Preset]: PresetConfig;
};

// some constants to keep text and preset in sync
const STANDARD_CPU = 1;
const STANDARD_RAM = 4;
const STANDARD_DISK = 3;

const PRESET_STANDARD_NAME = "Standard";

export const PRESETS: PresetEntries = {
standard: {
icon: "line-chart",
name: "Standard",
descr: "is a good choice for most users and students to get started",
name: PRESET_STANDARD_NAME,
descr:
"is a good choice for most users to get started and students in a course",
expect: [
"Run 2 or 3 Jupyter Notebooks at the same time,",
"Edit LaTeX, Markdown, and R Documents,",
`${STANDARD_DISK} GB disk space is sufficient to store many files and small datasets.`,
],
note: (
<Paragraph type="secondary">
You can start small with just a "Run Limit" of one and small quotas.
Later, if your usage incrases, you can edit your license to change the
"Run Limit" and/or the quotas. Read more about{" "}
<A href={"https://doc.cocalc.com/licenses.html"}>Managing Licenses</A>{" "}
in our documentation.
</Paragraph>
),
details: (
<>
You can run two or three Jupyter Notebooks in the same project at the
Expand All @@ -64,8 +84,45 @@ export const PRESETS: PresetEntries = {
instructor: {
icon: "slides",
name: "Instructor",
descr:
"is a good choice for the instructor's project when teaching a course",
descr: "for your instructor project when teaching a course",
expect: [
"Grade the work of students,",
"Run several Jupyter Notebooks at the same time¹,",
"Store the files of all students,",
"Make longer breaks without your project being shut down.",
],
note: (
<>
<Paragraph type="secondary">
For your instructor project, you only need one such license with a
"Run Limit" of 1. Apply that license via the{" "}
<A href={"https://doc.cocalc.com/project-settings.html#licenses"}>
project settings
</A>
. For the students, select a "{PRESET_STANDARD_NAME}" license with a
"Run Limit" of the number of students and distribute it via the{" "}
<A
href={
"https://doc.cocalc.com/teaching-upgrade-course.html#teacher-or-institute-pays-for-upgrades"
}
>
course configuration
</A>
.
</Paragraph>
<Paragraph type="secondary">
¹ Still, make sure to use the{" "}
<A
href={
"https://doc.cocalc.com/jupyter.html?highlight=halt%20button#use-the-halt-button-to-conserve-memory"
}
>
Halt button
</A>
.
</Paragraph>
</>
),
details: (
<>
The upgrade schema is suitable for grading the work of students: by
Expand Down Expand Up @@ -99,7 +156,29 @@ export const PRESETS: PresetEntries = {
research: {
icon: "users",
name: "Researcher",
descr: "is a good choice for a research group",
descr: "is a good choice for intesse usage or a research group",
expect: [
"Run many Jupyter Notebooks at once,",
"Run memory-intensive computations,",
"1 day idle-timeout is sufficient to not interrupt your work,",
"and to execute long-running calculations.",
"More disk space also allows you to store larger datasets.",
],
note: (
<>
<Paragraph type="secondary">
If you need <b>vastly more dedicated disk space, CPU or RAM</b>, you
should instead{" "}
<b>
rent a{" "}
<A href="https://doc.cocalc.com/compute_server.html">
compute server
</A>
.
</b>
</Paragraph>
</>
),
details: (
<>
This configuration allows the project to run many Jupyter Notebooks and
Expand Down
Loading

0 comments on commit 8686af1

Please sign in to comment.