Add project create template for image upload PWA (#109)

* Use image upload PWA template

* Set template URL from env

* Handle review changes

* Update readme and build app script

---------

Co-authored-by: neeraj <neeraj.rtly@gmail.com>
This commit is contained in:
Nabarun Gogoi 2024-02-26 17:54:35 +05:30 committed by GitHub
parent 6126c03eee
commit b48afed24f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 69 additions and 53 deletions

View File

@ -187,11 +187,12 @@
REACT_APP_GITHUB_CLIENT_ID = <CLIENT_ID> REACT_APP_GITHUB_CLIENT_ID = <CLIENT_ID>
``` ```
- Set `REACT_APP_GITHUB_TEMPLATE_REPO` in [.env](packages/frontend/.env) file - Set `REACT_APP_GITHUB_PWA_TEMPLATE_REPO` and `REACT_APP_GITHUB_IMAGE_UPLOAD_PWA_TEMPLATE_REPO` in [.env](packages/frontend/.env) file
```env ```env
# Set actual owner/name of the template repo that will be used for creating new repo # Set actual owner/name of the template repo that will be used for creating new repo
REACT_APP_GITHUB_TEMPLATE_REPO = cerc-io/test-progressive-web-app REACT_APP_GITHUB_PWA_TEMPLATE_REPO = cerc-io/test-progressive-web-app
REACT_APP_GITHUB_IMAGE_UPLOAD_PWA_TEMPLATE_REPO = cerc-io/image-upload-pwa-example
``` ```
### Frontend Production ### Frontend Production

View File

@ -12,7 +12,8 @@ fi
cat > $PKG_DIR/.env <<EOF cat > $PKG_DIR/.env <<EOF
REACT_APP_SERVER_URL = 'LACONIC_HOSTED_CONFIG_app_server_url' REACT_APP_SERVER_URL = 'LACONIC_HOSTED_CONFIG_app_server_url'
REACT_APP_GITHUB_CLIENT_ID = 'LACONIC_HOSTED_CONFIG_app_github_clientid' REACT_APP_GITHUB_CLIENT_ID = 'LACONIC_HOSTED_CONFIG_app_github_clientid'
REACT_APP_GITHUB_TEMPLATE_REPO = 'LACONIC_HOSTED_CONFIG_app_github_templaterepo' REACT_APP_GITHUB_PWA_TEMPLATE_REPO = 'LACONIC_HOSTED_CONFIG_app_github_pwa_templaterepo'
REACT_APP_GITHUB_IMAGE_UPLOAD_PWA_TEMPLATE_REPO = 'LACONIC_HOSTED_CONFIG_app_github_image_upload_templaterepo'
REACT_APP_WALLET_CONNECT_ID = 'LACONIC_HOSTED_CONFIG_app_wallet_connect_id' REACT_APP_WALLET_CONNECT_ID = 'LACONIC_HOSTED_CONFIG_app_wallet_connect_id'
EOF EOF

View File

@ -1,6 +1,7 @@
REACT_APP_SERVER_URL = 'http://localhost:8000' REACT_APP_SERVER_URL = 'http://localhost:8000'
REACT_APP_GITHUB_CLIENT_ID = REACT_APP_GITHUB_CLIENT_ID =
REACT_APP_GITHUB_TEMPLATE_REPO = REACT_APP_GITHUB_PWA_TEMPLATE_REPO =
REACT_APP_GITHUB_IMAGE_UPLOAD_PWA_TEMPLATE_REPO =
REACT_APP_WALLET_CONNECT_ID = REACT_APP_WALLET_CONNECT_ID =

View File

@ -1,27 +0,0 @@
[
{
"id": "1",
"name": "Progressive Web App (PWA)",
"icon": "^"
},
{
"id": "2",
"name": "Kotlin",
"icon": "^"
},
{
"id": "3",
"name": "React Native",
"icon": "^"
},
{
"id": "4",
"name": "Swift",
"icon": "^"
},
{
"id": "5",
"name": "Web app",
"icon": "^"
}
]

View File

@ -0,0 +1,32 @@
export default [
{
id: '1',
name: 'Progressive Web App (PWA)',
icon: '^',
repoFullName: `${process.env.REACT_APP_GITHUB_PWA_TEMPLATE_REPO}`,
},
{
id: '2',
name: 'Image Upload PWA',
icon: '^',
repoFullName: `${process.env.REACT_APP_GITHUB_IMAGE_UPLOAD_PWA_TEMPLATE_REPO}`,
},
{
id: '3',
name: 'Kotlin',
icon: '^',
repoFullName: '',
},
{
id: '4',
name: 'React Native',
icon: '^',
repoFullName: '',
},
{
id: '5',
name: 'Swift',
icon: '^',
repoFullName: '',
},
];

View File

@ -7,7 +7,7 @@ import { DeployStep, DeployStatus } from './DeployStep';
import { Stopwatch, setStopWatchOffset } from '../../StopWatch'; import { Stopwatch, setStopWatchOffset } from '../../StopWatch';
import ConfirmDialog from '../../shared/ConfirmDialog'; import ConfirmDialog from '../../shared/ConfirmDialog';
const INTERVAL_DURATION = 5000; const TIMEOUT_DURATION = 5000;
const Deploy = () => { const Deploy = () => {
const [searchParams] = useSearchParams(); const [searchParams] = useSearchParams();
const projectId = searchParams.get('projectId'); const projectId = searchParams.get('projectId');
@ -25,7 +25,7 @@ const Deploy = () => {
useEffect(() => { useEffect(() => {
const timerID = setTimeout(() => { const timerID = setTimeout(() => {
navigate(`/${orgSlug}/projects/create/success/${projectId}`); navigate(`/${orgSlug}/projects/create/success/${projectId}`);
}, INTERVAL_DURATION); }, TIMEOUT_DURATION);
return () => clearInterval(timerID); return () => clearInterval(timerID);
}, []); }, []);

View File

@ -1,5 +1,3 @@
export const GIT_TEMPLATE_LINK = `https://github.com/${process.env.REACT_APP_GITHUB_TEMPLATE_REPO}`;
export const SHORT_COMMIT_HASH_LENGTH = 8; export const SHORT_COMMIT_HASH_LENGTH = 8;
export const SERVER_GQL_PATH = 'graphql'; export const SERVER_GQL_PATH = 'graphql';

View File

@ -9,8 +9,7 @@ import {
import { Avatar } from '@material-tailwind/react'; import { Avatar } from '@material-tailwind/react';
import Stepper from '../../../../components/Stepper'; import Stepper from '../../../../components/Stepper';
import templateDetails from '../../../../assets/templates.json'; import templates from '../../../../assets/templates';
import { GIT_TEMPLATE_LINK } from '../../../../constants';
// TODO: Set dynamic route for template and load details from DB // TODO: Set dynamic route for template and load details from DB
const CreateWithTemplate = () => { const CreateWithTemplate = () => {
@ -33,7 +32,7 @@ const CreateWithTemplate = () => {
const [searchParams] = useSearchParams(); const [searchParams] = useSearchParams();
const template = templateDetails.find( const template = templates.find(
(template) => template.id === searchParams.get('templateId'), (template) => template.id === searchParams.get('templateId'),
); );
@ -49,8 +48,15 @@ const CreateWithTemplate = () => {
<Avatar variant="rounded" src="/gray.png" /> <Avatar variant="rounded" src="/gray.png" />
<div className="grow px-2">{template?.name}</div> <div className="grow px-2">{template?.name}</div>
<div> <div>
<a href={GIT_TEMPLATE_LINK} target="_blank" rel="noreferrer"> <a
^ {process.env.REACT_APP_GITHUB_TEMPLATE_REPO} href={`https://github.com/${template?.repoFullName}`}
target="_blank"
rel="noreferrer"
>
^{' '}
{Boolean(template?.repoFullName)
? template?.repoFullName
: 'Template not supported'}
</a> </a>
</div> </div>
</div> </div>
@ -59,7 +65,7 @@ const CreateWithTemplate = () => {
<Stepper activeStep={activeStep} stepperValues={stepperValues} /> <Stepper activeStep={activeStep} stepperValues={stepperValues} />
</div> </div>
<div className="col-span-2"> <div className="col-span-2">
<Outlet /> <Outlet context={{ template }} />
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import templateDetails from '../../../../assets/templates.json'; import templates from '../../../../assets/templates';
import TemplateCard from '../../../../components/projects/create/TemplateCard'; import TemplateCard from '../../../../components/projects/create/TemplateCard';
import RepositoryList from '../../../../components/projects/create/RepositoryList'; import RepositoryList from '../../../../components/projects/create/RepositoryList';
import ConnectAccount from '../../../../components/projects/create/ConnectAccount'; import ConnectAccount from '../../../../components/projects/create/ConnectAccount';
@ -13,7 +13,7 @@ const NewProject = () => {
<> <>
<h5 className="mt-4 ml-4">Start with template</h5> <h5 className="mt-4 ml-4">Start with template</h5>
<div className="grid grid-cols-3 p-4 gap-4"> <div className="grid grid-cols-3 p-4 gap-4">
{templateDetails.map((template) => { {templates.map((template) => {
return ( return (
<TemplateCard <TemplateCard
isGitAuth={Boolean(octokit)} isGitAuth={Boolean(octokit)}

View File

@ -1,6 +1,6 @@
import React, { useCallback, useEffect, useState } from 'react'; import React, { useCallback, useEffect, useState } from 'react';
import { useForm, Controller, SubmitHandler } from 'react-hook-form'; import { useForm, Controller, SubmitHandler } from 'react-hook-form';
import { useNavigate, useParams } from 'react-router-dom'; import { useNavigate, useOutletContext, useParams } from 'react-router-dom';
import toast from 'react-hot-toast'; import toast from 'react-hot-toast';
import assert from 'assert'; import assert from 'assert';
@ -9,6 +9,7 @@ import { Button, Option, Typography } from '@material-tailwind/react';
import { useOctokit } from '../../../../../context/OctokitContext'; import { useOctokit } from '../../../../../context/OctokitContext';
import { useGQLClient } from '../../../../../context/GQLClientContext'; import { useGQLClient } from '../../../../../context/GQLClientContext';
import AsyncSelect from '../../../../../components/shared/AsyncSelect'; import AsyncSelect from '../../../../../components/shared/AsyncSelect';
import { Template } from '../../../../../types';
type SubmitRepoValues = { type SubmitRepoValues = {
framework: string; framework: string;
@ -19,7 +20,7 @@ type SubmitRepoValues = {
const CreateRepo = () => { const CreateRepo = () => {
const { octokit } = useOctokit(); const { octokit } = useOctokit();
const { template } = useOutletContext<{ template: Template }>();
const client = useGQLClient(); const client = useGQLClient();
const { orgSlug } = useParams(); const { orgSlug } = useParams();
@ -35,12 +36,8 @@ const CreateRepo = () => {
setIsLoading(true); setIsLoading(true);
try { try {
assert( assert(template.repoFullName, 'Template URL not provided');
process.env.REACT_APP_GITHUB_TEMPLATE_REPO, const [owner, repo] = template.repoFullName.split('/');
'Config REACT_APP_GITHUB_TEMPLATE_REPO is not set in .env',
);
const [owner, repo] =
process.env.REACT_APP_GITHUB_TEMPLATE_REPO.split('/');
// TODO: Handle this functionality in backend // TODO: Handle this functionality in backend
const gitRepo = await octokit?.rest.repos.createUsingTemplate({ const gitRepo = await octokit?.rest.repos.createUsingTemplate({
@ -67,7 +64,7 @@ const CreateRepo = () => {
if (Boolean(addProject)) { if (Boolean(addProject)) {
setIsLoading(true); setIsLoading(true);
navigate( navigate(
`/${orgSlug}/projects/create/template/deploy?projectId=${addProject.id}`, `deploy?projectId=${addProject.id}&templateId=${template.id}`,
); );
} else { } else {
setIsLoading(false); setIsLoading(false);
@ -185,7 +182,7 @@ const CreateRepo = () => {
<Button <Button
className="bg-blue-500 rounded-xl p-2" className="bg-blue-500 rounded-xl p-2"
type="submit" type="submit"
disabled={isLoading} disabled={!Boolean(template.repoFullName) || isLoading}
loading={isLoading} loading={isLoading}
> >
Deploy ^ Deploy ^

View File

@ -57,3 +57,10 @@ export type EnvironmentVariablesFormValues = {
production: boolean; production: boolean;
}; };
}; };
export type Template = {
id: string;
name: string;
icon: string;
repoFullName: string;
};