Skip to content

Commit

Permalink
add models page
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-burel committed Oct 11, 2021
1 parent 7e09bb7 commit 0601119
Show file tree
Hide file tree
Showing 14 changed files with 531 additions and 19 deletions.
2 changes: 1 addition & 1 deletion src/components/layout/muiMdComponents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,10 @@ export const muiMdComponents = {
),
inlineCode: (props) => (
<Typography
component="span"
sx={{
backgroundColor: (theme) => theme.palette.grey["50"], // "primary.main",
color: vnColors.darkBlueApollo, // "primary.main",
display: "inline",
}}
>
<code {...props} />
Expand Down
4 changes: 4 additions & 0 deletions src/components/vn/learn/GetHelp.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
TODO: not sure how to inject this in an mdx page then
**Had some trouble with this first step?**

[Join us on Slack and ask your questions directly](http://slack.vulcanjs.org/)
61 changes: 61 additions & 0 deletions src/components/vn/learn/MultipleChoiceQuestion.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import {
Box,
Divider,
List,
ListItem,
ListItemButton,
ListSubheader,
Typography,
} from "@mui/material";
import { ReactNode, useState } from "react";

export interface MultipleChoiceQuestionProps {
question: string;
answers: Array<string>;
/** idx of the answer in the questions array (only one valid answer per choice) */
validAnswerIdx: number;
ifOk: ReactNode;
}
export const MultipleChoiceQuestion = ({
question,
answers,
validAnswerIdx,
ifOk,
}: MultipleChoiceQuestionProps) => {
const [currentAnswer, setCurrentAnswer] = useState<number | undefined>(
undefined
);
return (
<Box>
<List
subheader={
<ListSubheader>{question} (click on the right answer)</ListSubheader>
}
>
{answers.map((answer, idx) => {
return (
<ListItem key={idx}>
<ListItemButton
onClick={() => setCurrentAnswer(idx)}
selected={idx === currentAnswer}
>
{answer}
</ListItemButton>
</ListItem>
);
})}
</List>
{currentAnswer === validAnswerIdx ? ifOk : null}
{currentAnswer && currentAnswer !== validAnswerIdx ? (
<>
<Typography sx={{ color: "warning.main" }}>
Wrong answer...
</Typography>
<Typography sx={{ color: "secondary.main" }}>
Try another answer to unlock next step!
</Typography>
</>
) : null}
</Box>
);
};
36 changes: 22 additions & 14 deletions src/components/vn/learn/Steps.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { List, ListItem, ListItemButton } from "@mui/material";
import { List, ListItem, ListItemButton, Typography } from "@mui/material";
import { ReactNode, useEffect, useState } from "react";
import { useMulti } from "@vulcanjs/react-hooks";
import { User } from "~/models/user";
import { UserType } from "~/models/user";
import { useRouter } from "next/router";
import { S_IFSOCK } from "constants";

/**
* @client-only
Expand All @@ -29,6 +28,7 @@ const detectStep = ({ usersCount }) => {
// etc.
};
const useMaxStep = () => {
const currentStep = useCurrentStep();
const [step, setStep] = useState<number>(-1);

// various data needed to detect the step
Expand All @@ -46,17 +46,25 @@ const useMaxStep = () => {
setStep(nextStep);
}
}, [usersCount]);
return step;
// NOTE: when "forcing" a step, by accessing its url, it becomes the max step automatically
// (it's ok to access a step manually)
return Math.max(step, currentStep);
};

const steps = [
{ name: "0 - Install", path: "/learn/intro-online" },
{ name: "1 - Run", path: "/learn/intro-offline" },
{ name: "2 - Mongo", path: "/learn/mongo" },
{ name: "3 - Models", path: "/learn/about-models" },
{ name: "Done!", path: "/learn/final" },
];
const stepPaths = steps.map((s, idx) => {
return [s.path, idx] as const;
});

const useCurrentStep = () => {
const router = useRouter();
const { pathname } = router;
const stepPaths = [
["intro-online", 0],
["intro-offline", 1],
["mongo", 2],
] as const;
const currentStep = stepPaths.find(([pathMatch, step]) => {
if (pathname.match(pathMatch)) {
return true;
Expand All @@ -73,12 +81,7 @@ export const Steps = () => {
// be careful with step 0, that happens online
return (
<List>
{[
{ name: "0 - Install", path: "/learn/intro-online" },
{ name: "1 - Run", path: "/learn/intro-offline" },
{ name: "2 - Mongo", path: "/learn/mongo" },
{ name: "3 - Done!", path: "/learn/mongo" },
].map((step, stepIdx) => {
{steps.map((step, stepIdx) => {
return (
<ListItem key={step.name}>
<ListItemButton
Expand All @@ -94,6 +97,11 @@ export const Steps = () => {
);
};

/**
* Enable a step button or show a message if disabled
* @param param0
* @returns
*/
export const StepIfElse = ({
ifOk,
ifNotOk = null,
Expand Down
2 changes: 1 addition & 1 deletion src/lib/style/typography.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export const typeScale = {
h3: "1.5em",
h4: "1.3em",
h5: "1.2em",
p: "1em",
p: "1.05em",
helper: "0.8em" /* 14 px */,
legal: "0.7em",
};
59 changes: 59 additions & 0 deletions src/models/advancedModel.server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/**
* I am a sample model
* Replace me with your own
*/
import { VulcanDocument } from "@vulcanjs/schema";
import {
CreateGraphqlModelOptionsServer,
createGraphqlModelServer,
VulcanGraphqlSchemaServer,
} from "@vulcanjs/graphql/server";
import { createMongooseConnector } from "@vulcanjs/mongo";
import merge from "lodash/merge";
import { modelDef as modelDefShared } from "./sampleModel";

const schema: VulcanGraphqlSchemaServer = {
_id: {
type: String,
optional: true,
canRead: ["guests"],
},
userId: {
type: String,
optional: true,
canRead: ["guests"],
},
createdAt: {
type: Date,
optional: true,
canRead: ["admins"],
onCreate: () => {
return new Date();
},
},
someField: {
type: String,
optional: true,
canRead: ["guests"],
canUpdate: ["admins"],
canCreate: ["owners"],
searchable: true,
},
};

export interface SampleModelType extends VulcanDocument {
someField: string;
}

const modelDef: CreateGraphqlModelOptionsServer = merge({}, modelDefShared, {
schema,
// add other server only options here
graphql: {
/* ...*/
},
});
export const SampleModel = createGraphqlModelServer(modelDef);

export const SampleModelConnector = createMongooseConnector<SampleModelType>(
SampleModel
);
61 changes: 61 additions & 0 deletions src/models/advancedModel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/**
* I am a sample model
* Replace me with your own
*/
import { VulcanSchema, VulcanDocument } from "@vulcanjs/schema";
import {
createGraphqlModel,
CreateGraphqlModelOptionsShared,
} from "@vulcanjs/graphql";

const schema: VulcanSchema = {
_id: {
type: String,
optional: true,
canRead: ["guests"],
},
userId: {
type: String,
optional: true,
canRead: ["guests"],
},
createdAt: {
type: Date,
optional: true,
canRead: ["admins"],
onCreate: () => {
return new Date();
},
},
someField: {
type: String,
optional: true,
canRead: ["guests"],
canUpdate: ["admins"],
canCreate: ["owners"],
searchable: true,
},
};

export interface SampleModelType extends VulcanDocument {
someField: string;
}

const name = "Sample"; // Change this value when creating your own model
const typeName = name;
const multiTypeName = "Samples"; // Change this value when creating your own model
export const modelDef: CreateGraphqlModelOptionsShared = {
name: "sample",
schema,
graphql: {
typeName,
multiTypeName,
},
permissions: {
canCreate: ["member"],
canUpdate: ["owners", "admins"],
canDelete: ["owners", "admins"],
canRead: ["members", "admins"],
},
};
export const SampleModel = createGraphqlModel(modelDef);
6 changes: 5 additions & 1 deletion src/models/sampleModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,19 @@ import {
} from "@vulcanjs/graphql";

const schema: VulcanSchema = {
/** Unique id of the document in the database. You'll want to leave this field as is. */
_id: {
type: String,
optional: true,
canRead: ["guests"],
},
/** _id of the user that created the document. This special field is used to handle the "ownership" of the document. */
userId: {
type: String,
optional: true,
canRead: ["guests"],
},
/** Timestamps handled by the database (you could also define updatedAt) */
createdAt: {
type: Date,
optional: true,
Expand All @@ -27,17 +30,18 @@ const schema: VulcanSchema = {
return new Date();
},
},
// Your own custom fields. Press ctrl+space to see the possible fields.
someField: {
type: String,
optional: true,
canRead: ["guests"],
canUpdate: ["admins"],
canCreate: ["owners"],
searchable: true,
},
};

export interface SampleModelType extends VulcanDocument {
// List your custom fields (_id, userId, createdAt, updatedAt and slug are already in VulcanDocument type)
someField: string;
}

Expand Down
Loading

0 comments on commit 0601119

Please sign in to comment.