Neon / portal template support (#713)
TODOs: - [x] Do restart when checkout / restore if there is a DB - [x] List all branches (branch id, name, date) - [x] Allow checking out versions with no DB - [x] safeguard to never delete main branches - [x] create app hook for neon template - [x] weird UX with connector on configure panel - [x] tiny neon logo in connector - [x] deploy to vercel - [x] build forgot password page - [x] what about email setup - [x] lots of imgix errors - [x] edit file - db snapshot - [x] DYAD_DISABLE_DB_PUSH - [ ] update portal doc - [x] switch preview branch to be read-only endpoint - [x] disable supabase sys prompt if neon is enabled - [ ] https://payloadcms.com/docs/upload/storage-adapters - [x] need to use main branch... Phase 2? - [x] generate DB migrations
This commit is contained in:
@@ -4,17 +4,22 @@ import { IpcClient } from "@/ipc/ipc_client";
|
||||
import { useSettings } from "@/hooks/useSettings";
|
||||
import { CommunityCodeConsentDialog } from "./CommunityCodeConsentDialog";
|
||||
import type { Template } from "@/shared/templates";
|
||||
import { Button } from "./ui/button";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { showWarning } from "@/lib/toast";
|
||||
|
||||
interface TemplateCardProps {
|
||||
template: Template;
|
||||
isSelected: boolean;
|
||||
onSelect: (templateId: string) => void;
|
||||
onCreateApp: () => void;
|
||||
}
|
||||
|
||||
export const TemplateCard: React.FC<TemplateCardProps> = ({
|
||||
template,
|
||||
isSelected,
|
||||
onSelect,
|
||||
onCreateApp,
|
||||
}) => {
|
||||
const { settings, updateSettings } = useSettings();
|
||||
const [showConsentDialog, setShowConsentDialog] = useState(false);
|
||||
@@ -26,6 +31,11 @@ export const TemplateCard: React.FC<TemplateCardProps> = ({
|
||||
return;
|
||||
}
|
||||
|
||||
if (template.requiresNeon && !settings?.neon?.accessToken) {
|
||||
showWarning("Please connect your Neon account to use this template.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, proceed with selection
|
||||
onSelect(template.id);
|
||||
};
|
||||
@@ -93,7 +103,7 @@ export const TemplateCard: React.FC<TemplateCardProps> = ({
|
||||
>
|
||||
{template.title}
|
||||
</h2>
|
||||
{template.isOfficial && (
|
||||
{template.isOfficial && !template.isExperimental && (
|
||||
<span
|
||||
className={`text-xs font-semibold px-2 py-0.5 rounded-full ${
|
||||
isSelected
|
||||
@@ -104,8 +114,13 @@ export const TemplateCard: React.FC<TemplateCardProps> = ({
|
||||
Official
|
||||
</span>
|
||||
)}
|
||||
{template.isExperimental && (
|
||||
<span className="text-xs font-semibold px-2 py-0.5 rounded-full bg-yellow-100 text-yellow-800 dark:bg-yellow-700 dark:text-yellow-200">
|
||||
Experimental
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<p className="text-sm text-gray-500 dark:text-gray-400 mb-3 h-8 overflow-y-auto">
|
||||
<p className="text-sm text-gray-500 dark:text-gray-400 mb-3 h-10 overflow-y-auto">
|
||||
{template.description}
|
||||
</p>
|
||||
{template.githubUrl && (
|
||||
@@ -121,6 +136,20 @@ export const TemplateCard: React.FC<TemplateCardProps> = ({
|
||||
<ArrowLeft className="w-4 h-4 ml-1 transform rotate-180" />
|
||||
</a>
|
||||
)}
|
||||
|
||||
<Button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
onCreateApp();
|
||||
}}
|
||||
size="sm"
|
||||
className={cn(
|
||||
"w-full bg-indigo-600 hover:bg-indigo-700 text-white font-semibold mt-2",
|
||||
settings?.selectedTemplateId !== template.id && "invisible",
|
||||
)}
|
||||
>
|
||||
Create App
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user