Skip to content

Commit a2c28b1

Browse files
committed
migrate next template
1 parent 8e69a3f commit a2c28b1

File tree

5 files changed

+124
-111
lines changed

5 files changed

+124
-111
lines changed

apps/create-hypergraph/template-nextjs/Components/Space/PrivateSpace.tsx

Lines changed: 48 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
} from '@graphprotocol/hypergraph-react';
1313
import { useState } from 'react';
1414

15-
import { Address } from '@/app/schema';
15+
import { Project } from '@/app/schema';
1616
import { Button } from '../ui/button';
1717

1818
export function PrivateSpaceWrapper({ spaceid }: Readonly<{ spaceid: string }>) {
@@ -25,11 +25,12 @@ export function PrivateSpaceWrapper({ spaceid }: Readonly<{ spaceid: string }>)
2525

2626
function PrivateSpace() {
2727
const { name, ready } = useSpace({ mode: 'private' });
28-
const { data: addresses } = useQuery(Address, { mode: 'private' });
28+
const { data: projects } = useQuery(Project, { mode: 'private' });
2929
const { data: publicSpaces } = useSpaces({ mode: 'public' });
3030
const [selectedSpace, setSelectedSpace] = useState<string>('');
31-
const createAddress = useCreateEntity(Address);
32-
const [addressName, setAddressName] = useState('');
31+
const createProject = useCreateEntity(Project);
32+
const [projectName, setProjectName] = useState('');
33+
const [projectDescription, setProjectDescription] = useState('');
3334
const { getSmartSessionClient } = useHypergraphApp();
3435

3536
if (!ready) {
@@ -45,32 +46,33 @@ function PrivateSpace() {
4546

4647
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
4748
e.preventDefault();
48-
createAddress({ name: addressName, description: 'Beautiful address' });
49-
setAddressName('');
49+
createProject({ name: projectName, description: projectDescription });
50+
setProjectName('');
51+
setProjectDescription('');
5052
};
5153

52-
const publishToPublicSpace = async (address: Address) => {
54+
const publishToPublicSpace = async (project: Project) => {
5355
if (!selectedSpace) {
5456
alert('No space selected');
5557
return;
5658
}
5759
try {
58-
const { ops } = await preparePublish({ entity: address, publicSpace: selectedSpace });
60+
const { ops } = await preparePublish({ entity: project, publicSpace: selectedSpace });
5961
const smartSessionClient = await getSmartSessionClient();
6062
if (!smartSessionClient) {
6163
throw new Error('Missing smartSessionClient');
6264
}
6365
const publishResult = await publishOps({
6466
ops,
6567
space: selectedSpace,
66-
name: 'Publish Address',
68+
name: 'Publish Project',
6769
walletClient: smartSessionClient,
6870
});
6971
console.log(publishResult, ops);
70-
alert('Address published to public space');
72+
alert('Project published to public space');
7173
} catch (error) {
7274
console.error(error);
73-
alert('Error publishing address to public space');
75+
alert('Error publishing project to public space');
7476
}
7577
};
7678

@@ -94,17 +96,30 @@ function PrivateSpace() {
9496
Address Name
9597
</label>
9698
<input
97-
id="address-name"
99+
id="project-name"
98100
type="text"
99-
value={addressName}
100-
onChange={(e) => setAddressName(e.target.value)}
101-
placeholder="Enter address name..."
101+
value={projectName}
102+
onChange={(e) => setProjectName(e.target.value)}
103+
placeholder="Enter project name..."
102104
className="w-full px-3 py-2 border border-input bg-background rounded-md text-sm transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:border-transparent"
103105
required
104106
/>
105107
</div>
106-
<Button type="submit" className="w-full" disabled={!addressName.trim()}>
107-
Create Address
108+
<div className="space-y-2">
109+
<label htmlFor="project-description" className="text-sm font-medium text-card-foreground">
110+
Project Description
111+
</label>
112+
<input
113+
id="project-description"
114+
type="text"
115+
value={projectDescription}
116+
onChange={(e) => setProjectDescription(e.target.value)}
117+
placeholder="Enter project description..."
118+
className="w-full px-3 py-2 border border-input bg-background rounded-md text-sm transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:border-transparent"
119+
/>
120+
</div>
121+
<Button type="submit" className="w-full" disabled={!projectName.trim()}>
122+
Create Project
108123
</Button>
109124
</form>
110125
</div>
@@ -114,18 +129,23 @@ function PrivateSpace() {
114129
<div className="space-y-6">
115130
<div className="bg-card border rounded-lg p-6 shadow-sm">
116131
<h2 className="text-xl font-semibold text-card-foreground mb-4">
117-
Your Addresses ({addresses?.length || 0})
132+
Your Projects ({projects?.length || 0})
118133
</h2>
119134

120-
{addresses && addresses.length > 0 ? (
135+
{projects && projects.length > 0 ? (
121136
<div className="space-y-4">
122-
{addresses.map((address) => (
123-
<div key={address.id} className="border border-border rounded-lg p-4 bg-background">
137+
{projects.map((project) => (
138+
<div key={project.id} className="border border-border rounded-lg p-4 bg-background">
139+
<div className="flex items-center justify-between mb-3">
140+
<h3 className="font-medium text-foreground">{project.name}</h3>
141+
</div>
142+
143+
<div className="flex items-center justify-between mb-3">
144+
<p className="text-xs text-muted-foreground">ID: {project.id}</p>
145+
</div>
146+
124147
<div className="flex items-center justify-between mb-3">
125-
<h3 className="font-medium text-foreground">{address.name}</h3>
126-
<span className="text-xs text-muted-foreground bg-muted px-2 py-1 rounded">
127-
ID: {address.id.slice(0, 8)}...
128-
</span>
148+
<p className="text-sm text-muted-foreground">{project.description}</p>
129149
</div>
130150

131151
<div className="space-y-3">
@@ -149,7 +169,7 @@ function PrivateSpace() {
149169
</div>
150170

151171
<Button
152-
onClick={() => publishToPublicSpace(address)}
172+
onClick={() => publishToPublicSpace(project)}
153173
disabled={!selectedSpace}
154174
variant="outline"
155175
size="sm"
@@ -178,8 +198,8 @@ function PrivateSpace() {
178198
/>
179199
</svg>
180200
</div>
181-
<p className="text-muted-foreground">No addresses created yet</p>
182-
<p className="text-sm text-muted-foreground mt-1">Create your first address using the form</p>
201+
<p className="text-muted-foreground">No projects created yet</p>
202+
<p className="text-sm text-muted-foreground mt-1">Create your first project using the form</p>
183203
</div>
184204
)}
185205
</div>

apps/create-hypergraph/template-nextjs/Components/Space/PublicSpace.tsx

Lines changed: 66 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import { HypergraphSpaceProvider, useQuery, useSpace } from '@graphprotocol/hypergraph-react';
44

5-
import { Address } from '@/app/schema';
5+
import { Project } from '@/app/schema';
66

77
export function PublicSpaceWrapper({ spaceid }: Readonly<{ spaceid: string }>) {
88
return (
@@ -14,7 +14,7 @@ export function PublicSpaceWrapper({ spaceid }: Readonly<{ spaceid: string }>) {
1414

1515
function PublicSpace() {
1616
const { ready, name } = useSpace({ mode: 'public' });
17-
const { data: addresses } = useQuery(Address, { mode: 'public' });
17+
const { data: projects, isPending } = useQuery(Project, { mode: 'public' });
1818

1919
if (!ready) {
2020
return (
@@ -41,77 +41,74 @@ function PublicSpace() {
4141

4242
{/* Main Content */}
4343
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
44-
<div className="bg-white rounded-lg shadow-sm border border-slate-200">
45-
<div className="px-6 py-4 border-b border-slate-200">
46-
<h2 className="text-xl font-semibold text-slate-900">Addresses</h2>
47-
<p className="text-slate-600 text-sm mt-1">
48-
{addresses ? `${addresses.length} addresses found` : 'Loading addresses...'}
49-
</p>
50-
</div>
44+
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
45+
{projects.map((project) => (
46+
<div
47+
key={project.id}
48+
className="group relative bg-white rounded-2xl shadow-lg hover:shadow-2xl transition-all duration-300 overflow-hidden border border-gray-100 hover:border-blue-200 transform hover:-translate-y-1 z-10"
49+
>
50+
{/* Gradient overlay */}
51+
<div className="absolute inset-0 bg-gradient-to-br from-blue-50 to-purple-50 opacity-0 group-hover:opacity-100 transition-opacity duration-300" />
5152

52-
<div className="p-6">
53-
{!addresses ? (
54-
<div className="space-y-3">
55-
{[...Array(3)].map((_, i) => (
56-
<div key={i} className="animate-pulse">
57-
<div className="h-4 bg-slate-200 rounded w-3/4" />
58-
</div>
59-
))}
60-
</div>
61-
) : addresses.length > 0 ? (
62-
<div className="grid gap-3">
63-
{addresses.map((address) => (
64-
<div
65-
key={address.id}
66-
className="group p-4 rounded-lg border border-slate-200 hover:border-slate-300 hover:shadow-sm transition-all duration-200 bg-slate-50 hover:bg-white"
67-
>
68-
<div className="flex items-center justify-between">
69-
<div className="flex items-center space-x-3">
70-
<div className="w-8 h-8 bg-blue-100 rounded-full flex items-center justify-center">
71-
<span className="text-blue-600 font-medium text-sm">
72-
{address.name.charAt(0).toUpperCase()}
73-
</span>
74-
</div>
75-
<div>
76-
<h3 className="font-medium text-slate-900 group-hover:text-blue-600 transition-colors">
77-
{address.name}
78-
</h3>
79-
<p className="text-sm text-slate-500">Address ID: {address.id}</p>
80-
</div>
81-
</div>
82-
<div className="opacity-0 group-hover:opacity-100 transition-opacity">
83-
<svg className="w-5 h-5 text-slate-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
84-
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
85-
</svg>
86-
</div>
87-
</div>
88-
</div>
89-
))}
90-
</div>
91-
) : (
92-
<div className="text-center py-12">
93-
<div className="w-16 h-16 bg-slate-100 rounded-full flex items-center justify-center mx-auto mb-4">
94-
<svg className="w-8 h-8 text-slate-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
95-
<path
96-
strokeLinecap="round"
97-
strokeLinejoin="round"
98-
strokeWidth={2}
99-
d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z"
100-
/>
101-
<path
102-
strokeLinecap="round"
103-
strokeLinejoin="round"
104-
strokeWidth={2}
105-
d="M15 11a3 3 0 11-6 0 3 3 0 016 0z"
106-
/>
107-
</svg>
53+
{/* Content */}
54+
<div className="relative p-6">
55+
{/* Project icon/avatar */}
56+
<div className="w-12 h-12 bg-gradient-to-br from-blue-500 to-purple-600 rounded-xl flex items-center justify-center mb-4 group-hover:scale-110 transition-transform duration-300 overflow-hidden">
57+
<span className="text-white font-bold text-lg">{project.name.charAt(0).toUpperCase()}</span>
10858
</div>
109-
<h3 className="text-lg font-medium text-slate-900 mb-2">No addresses found</h3>
110-
<p className="text-slate-600">This space doesn&apos;t have any addresses yet.</p>
59+
60+
{/* Project name */}
61+
<h3 className="text-xl font-bold text-gray-900 mb-2 group-hover:text-blue-600 transition-colors duration-300">
62+
{project.name}
63+
</h3>
64+
65+
{/* Project ID */}
66+
<p className="text-[10px] text-gray-500 mb-2 font-mono">{project.id}</p>
67+
68+
{/* Project description */}
69+
{project.description && (
70+
<p className="text-sm text-gray-600 mb-2 line-clamp-2">{project.description}</p>
71+
)}
72+
73+
{/* Project xUrl */}
74+
{project.xUrl && (
75+
<a
76+
href={project.xUrl}
77+
target="_blank"
78+
rel="noopener noreferrer"
79+
className="text-sm text-blue-600 hover:text-blue-800 transition-colors duration-200 flex items-center gap-1"
80+
>
81+
<svg className="w-4 h-4" fill="currentColor" viewBox="0 0 24 24">
82+
<path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z" />
83+
</svg>
84+
View on X
85+
</a>
86+
)}
11187
</div>
112-
)}
113-
</div>
88+
89+
{/* Decorative corner accent */}
90+
<div className="absolute top-0 right-0 w-16 h-16 bg-gradient-to-br from-blue-400 to-purple-500 opacity-10 group-hover:opacity-20 transition-opacity duration-300 transform rotate-45 translate-x-8 -translate-y-8" />
91+
</div>
92+
))}
11493
</div>
94+
95+
{/* Empty state */}
96+
{isPending === false && projects.length === 0 && (
97+
<div className="text-center py-16">
98+
<div className="w-24 h-24 bg-gradient-to-br from-blue-100 to-purple-100 rounded-full flex items-center justify-center mx-auto mb-6">
99+
<svg className="w-12 h-12 text-blue-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
100+
<path
101+
strokeLinecap="round"
102+
strokeLinejoin="round"
103+
strokeWidth={2}
104+
d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10"
105+
/>
106+
</svg>
107+
</div>
108+
<h3 className="text-xl font-semibold text-gray-900 mb-2">No Projects Found</h3>
109+
<p className="text-gray-500">There are currently no public projects available to explore.</p>
110+
</div>
111+
)}
115112
</div>
116113
</div>
117114
);

apps/create-hypergraph/template-nextjs/app/explore-public-knowledge/layout.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,20 @@ import { ExploreTabs } from '../../Components/explore-tabs';
33
export default function ExplorePublicKnowledgeLayout({ children }: { children: React.ReactNode }) {
44
return (
55
<div className="container mx-auto px-4 py-8">
6-
<div className="text-center mb-12">
6+
<div className="text-center mb-6">
77
<h1 className="text-4xl font-bold mb-4 bg-gradient-to-r from-blue-600 to-purple-600 bg-clip-text text-transparent">
88
Explore Public Knowledge
99
</h1>
1010
<p className="text-lg text-muted-foreground max-w-2xl mx-auto">
11-
This page demonstrates how to query public data from a space. No authentication is required.
11+
This page demonstrates how to query public data from the public space{' '}
12+
<span className="inline-flex items-center rounded-full border bg-accent/60 text-accent-foreground px-2 py-0.5 text-sm align-middle">
13+
Crypto
14+
</span>{' '}
15+
with the ID{' '}
16+
<span className="inline-flex items-center rounded-full border bg-accent/60 text-accent-foreground px-2 py-0.5 text-xs font-mono align-middle">
17+
b2565802-3118-47be-91f2-e59170735bac
18+
</span>
19+
. No authentication is required.
1220
</p>
1321
</div>
1422

apps/create-hypergraph/template-nextjs/app/mapping.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,6 @@ import type { Mapping } from '@graphprotocol/hypergraph';
22
import { Id } from '@graphprotocol/hypergraph';
33

44
export const mapping: Mapping.Mapping = {
5-
Address: {
6-
typeIds: [Id('5c6e72fb-8340-47c0-8281-8be159ecd495')],
7-
properties: {
8-
name: Id('a126ca53-0c8e-48d5-b888-82c734c38935'),
9-
description: Id('9b1f76ff-9711-404c-861e-59dc3fa7d037'),
10-
},
11-
},
125
Image: {
136
typeIds: [Id('ba4e4146-0010-499d-a0a3-caaa7f579d0e')],
147
properties: {

apps/create-hypergraph/template-nextjs/app/schema.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
import { Entity, Type } from '@graphprotocol/hypergraph';
22

3-
export class Address extends Entity.Class<Address>('Address')({
4-
name: Type.String,
5-
description: Type.String,
6-
}) {}
7-
83
export class Image extends Entity.Class<Image>('Image')({
94
url: Type.String,
105
}) {}

0 commit comments

Comments
 (0)