Skip to content

Commit 4861aaa

Browse files
committed
fix: add all website links
1 parent 673bf7a commit 4861aaa

File tree

9 files changed

+190
-80
lines changed

9 files changed

+190
-80
lines changed

lib/src/app/external_links.dart

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
enum ExternalLink {
2+
youTubePlaylist('https://www.youtube.com/playlist?list=PL4dBIh1xps-HIYvaEIbLWHZqt_WGBfpx3'),
3+
youTubeVibeCoding('https://www.youtube.com/playlist?list=PL4dBIh1xps-GLrzqijiTRuzdtxP3bfqsQ'),
4+
forumCategory('https://forum.itsallwidgets.com/c/ai/46'),
5+
forumChat('https://forum.itsallwidgets.com/chat/c/fc-ai-circle/40'),
6+
surveyCommunity('https://forms.gle/JrC11pxRz6TLyB2L9'),
7+
surveyContributors('https://forms.gle/AcoThJ6E9yxxe8hdA'),
8+
socialBlueSky('https://bsky.app/profile/fluttercommunity.dev'),
9+
socialTwitterX('https://x.com/FlutterComm'),
10+
socialMastodon('https://fluttercommunity.social/@FlutterComm'),
11+
socialGitHub('https://github.com/fluttercommunity/fc_ai_circle'),
12+
socialMedium('https://medium.com/flutter-community'),
13+
;
14+
15+
const ExternalLink(this.url);
16+
17+
final String url;
18+
}

lib/src/components/footer.dart

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1+
import 'package:fc_ai_circle/src/app/external_links.dart';
12
import 'package:jaspr/browser.dart';
3+
import 'package:jaspr_router/jaspr_router.dart';
4+
import 'package:fc_ai_circle/src/pages/builders_page.dart';
5+
import 'package:fc_ai_circle/src/pages/starters_page.dart';
26

37
class Footer extends StatelessComponent {
48
@override
@@ -8,19 +12,25 @@ class Footer extends StatelessComponent {
812
div(classes: 'footer-grid', [
913
FooterColumn(
1014
title: 'Community',
11-
links: ['About', 'Mission', 'Join the Circle', 'Start Contributing'],
15+
links: [
16+
(path: '#', label: 'What is Agentic Flutter?'),
17+
(path: '#', label: 'Take the contributors survey'),
18+
],
1219
),
1320
FooterColumn(
1421
title: 'Resources',
15-
links: ['Docs', 'Templates', 'Survey', 'Events'],
16-
),
17-
FooterColumn(
18-
title: 'Channels',
19-
links: ['YouTube', 'Twitter', 'Forum', 'GitHub'],
22+
links: [
23+
(path: StartersPage.path, label: 'Starters'),
24+
(path: BuildersPage.path, label: 'Builders'),
25+
],
2026
),
27+
div([]),
2128
FooterColumn(
2229
title: 'Legal',
23-
links: ['Privacy', 'Terms', 'Code of Conduct', 'Licensing'],
30+
links: [
31+
(path: '#', label: 'Privacy Policy'),
32+
(path: '#', label: 'Code of Conduct'),
33+
],
2434
),
2535
]),
2636
div(classes: 'footer-bottom', [
@@ -30,24 +40,29 @@ class Footer extends StatelessComponent {
3040
),
3141
div(classes: 'social-links', [
3242
SocialLink(
43+
link: ExternalLink.socialBlueSky,
3344
icon: 'fa-bluesky',
3445
label: 'BlueSky',
35-
href: 'https://bsky.app/profile/fluttercommunity.dev',
3646
),
3747
SocialLink(
48+
link: ExternalLink.socialTwitterX,
3849
icon: 'fa-x-twitter',
3950
label: 'Twitter',
40-
href: 'https://x.com/fluttercomm',
4151
),
4252
SocialLink(
53+
link: ExternalLink.socialMastodon,
4354
icon: 'fa-mastodon',
4455
label: 'Mastodon',
45-
href: 'https://fluttercommunity.social/@FlutterComm',
4656
),
4757
SocialLink(
58+
link: ExternalLink.socialGitHub,
4859
icon: 'fa-github',
4960
label: 'GitHub',
50-
href: 'https://github.com/fluttercommunity/fc_ai_circle',
61+
),
62+
SocialLink(
63+
link: ExternalLink.socialMedium,
64+
icon: 'fa-medium',
65+
label: 'Medium',
5166
),
5267
]),
5368
]),
@@ -64,7 +79,7 @@ class FooterColumn extends StatelessComponent {
6479
});
6580

6681
final String title;
67-
final List<String> links;
82+
final List<({String path, String label})> links;
6883

6984
@override
7085
Iterable<Component> build(BuildContext context) sync* {
@@ -73,7 +88,11 @@ class FooterColumn extends StatelessComponent {
7388
ul([
7489
for (var link in links) //
7590
li([
76-
a(href: '#', [text(link)])
91+
a(
92+
href: link.path,
93+
onClick: () => Router.of(context).push(link.path),
94+
[text(link.label)],
95+
)
7796
]),
7897
]),
7998
]);
@@ -83,12 +102,12 @@ class FooterColumn extends StatelessComponent {
83102
class SocialLink extends StatefulComponent {
84103
const SocialLink({
85104
super.key,
86-
required this.href,
105+
required this.link,
87106
required this.icon,
88107
required this.label,
89108
});
90109

91-
final String href;
110+
final ExternalLink link;
92111
final String icon;
93112
final String label;
94113

@@ -102,7 +121,7 @@ class _SocialLinkState extends State<SocialLink> {
102121
@override
103122
Iterable<Component> build(BuildContext context) sync* {
104123
yield a(
105-
href: component.href,
124+
href: component.link.url,
106125
target: Target.blank,
107126
attributes: {
108127
'title': component.label,

lib/src/components/navbar.dart

Lines changed: 74 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,81 @@
1+
import 'package:fc_ai_circle/src/app/external_links.dart';
12
import 'package:fc_ai_circle/src/components/take_survey.dart';
23
import 'package:jaspr/browser.dart';
4+
import 'package:jaspr_router/jaspr_router.dart' show Router;
5+
import 'package:fc_ai_circle/src/pages/builders_page.dart';
6+
import 'package:fc_ai_circle/src/pages/home_page.dart';
7+
import 'package:fc_ai_circle/src/pages/starters_page.dart';
8+
import 'package:web/web.dart' show window;
9+
10+
class Navbar extends StatefulComponent {
11+
const Navbar({super.key});
12+
13+
@override
14+
State<Navbar> createState() => _NavbarState();
15+
}
16+
17+
class _NavbarState extends State<Navbar> {
18+
@override
19+
Iterable<Component> build(BuildContext context) sync* {
20+
yield nav(
21+
id: 'navbar',
22+
classes: 'navbar',
23+
[
24+
div(classes: 'container', [
25+
a(
26+
href: HomePage.path,
27+
onClick: () => Router.of(context).push(HomePage.path),
28+
classes: 'navbar-brand',
29+
[
30+
img(
31+
src: '/images/logo_1x.png',
32+
alt: 'Flutter Community AI Circle',
33+
)
34+
],
35+
),
36+
div(
37+
classes: 'nav-links',
38+
[
39+
_NavItem(path: '/', label: 'Home'),
40+
_NavItem(path: StartersPage.path, label: 'Starters'),
41+
_NavItem(path: BuildersPage.path, label: 'Builders'),
42+
_NavItem(link: ExternalLink.youTubePlaylist, label: 'YouTube'),
43+
_NavItem(link: ExternalLink.socialGitHub, label: 'GitHub'),
44+
_NavItem(link: ExternalLink.forumCategory, label: 'Forum'),
45+
],
46+
),
47+
TakeSurvey(),
48+
]),
49+
],
50+
);
51+
}
52+
}
53+
54+
class _NavItem extends StatelessComponent {
55+
const _NavItem({
56+
this.path,
57+
this.link,
58+
required this.label,
59+
});
60+
61+
final String? path;
62+
final ExternalLink? link;
63+
final String label;
364

4-
class Navbar extends StatelessComponent {
565
@override
666
Iterable<Component> build(BuildContext context) sync* {
7-
yield nav(classes: 'navbar', [
8-
div(classes: 'container', [
9-
a(
10-
href: '/',
11-
classes: 'navbar-brand',
12-
[
13-
img(
14-
src: '/images/logo_1x.png',
15-
alt: 'Flutter Community AI Circle',
16-
)
17-
],
18-
),
19-
div(
20-
classes: 'nav-links',
21-
[
22-
a(href: '/', classes: 'nav-link', [text('Home')]),
23-
a(href: '/starters', classes: 'nav-link', [text('Starters')]),
24-
a(href: '/builders', classes: 'nav-link', [text('Builders')]),
25-
a(href: '/youtube', classes: 'nav-link', [text('YouTube')]),
26-
a(href: '/github', classes: 'nav-link', [text('GitHub')]),
27-
a(href: '/forum', classes: 'nav-link', [text('Forum')]),
28-
],
29-
),
30-
TakeSurvey(),
31-
]),
32-
]);
67+
// TODO: selected state?
68+
final selected = window.location.pathname == path;
69+
yield a(
70+
classes: [
71+
'nav-link',
72+
if (selected) //
73+
'nav-selected',
74+
].join(' '),
75+
href: path ?? link!.url,
76+
target: link != null ? Target.blank : null,
77+
onClick: path != null ? () => Router.of(context).push(path!) : null,
78+
[text(label)],
79+
);
3380
}
3481
}

lib/src/components/take_survey.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import 'package:fc_ai_circle/src/app/external_links.dart';
12
import 'package:jaspr/browser.dart';
23

34
class TakeSurvey extends StatelessComponent {
@@ -6,7 +7,8 @@ class TakeSurvey extends StatelessComponent {
67
@override
78
Iterable<Component> build(BuildContext context) sync* {
89
yield a(
9-
href: '/take_survey',
10+
href: ExternalLink.surveyCommunity.url,
11+
target: Target.blank,
1012
classes: 'cta_button',
1113
[text('Take the Survey')],
1214
);

lib/src/layouts/page_layout.dart

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,21 @@ import 'package:jaspr/browser.dart';
55
class PageLayout extends StatelessComponent {
66
const PageLayout({
77
super.key,
8-
required this.child,
8+
required this.children,
99
});
1010

11-
final Component child;
11+
final Iterable<Component> children;
1212

1313
@override
1414
Iterable<Component> build(BuildContext context) sync* {
15-
yield DomComponent(
16-
tag: 'div',
17-
classes: 'app-wrapper',
18-
children: [
15+
yield div(
16+
classes: 'site-frame',
17+
[
1918
Navbar(),
20-
child,
19+
div(
20+
classes: 'page-layout container',
21+
[...children],
22+
),
2123
Footer(),
2224
],
2325
);

lib/src/pages/builders_page.dart

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ import 'package:jaspr_router/jaspr_router.dart';
55
class BuildersPage extends StatelessComponent {
66
const BuildersPage({super.key});
77

8+
static var path = '/builders';
9+
810
static Route route() {
911
return Route(
10-
path: '/builders',
12+
path: path,
1113
title: 'Builders',
1214
builder: (BuildContext context, RouteState state) => BuildersPage(),
1315
);
@@ -16,9 +18,20 @@ class BuildersPage extends StatelessComponent {
1618
@override
1719
Iterable<Component> build(BuildContext context) sync* {
1820
yield PageLayout(
19-
child: h1(
20-
[text('Builders')],
21-
),
21+
children: [
22+
h1([text('Builders')]),
23+
h2([text('Our Mission 🎯')]),
24+
p([text('We aim to:')]),
25+
ul([
26+
li([
27+
text('Create accessible resources for Flutter developers '
28+
'to incorporate AI into their apps')
29+
]),
30+
li([text('Explore and share best practices for responsible AI implementation')]),
31+
li([text('Build a supportive community for experimentation and learning')]),
32+
li([text('Develop open-source starter kits and reference implementations')]),
33+
]),
34+
],
2235
);
2336
}
2437
}

lib/src/pages/home_page.dart

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
import 'package:fc_ai_circle/src/components/take_survey.dart';
22
import 'package:fc_ai_circle/src/layouts/page_layout.dart';
3+
import 'package:fc_ai_circle/src/pages/builders_page.dart';
34
import 'package:jaspr/browser.dart';
45
import 'package:jaspr_router/jaspr_router.dart';
56

67
class HomePage extends StatelessComponent {
78
const HomePage({super.key});
89

10+
static const path = '/';
11+
912
static Iterable<Route> route() sync* {
1013
yield Route(
1114
path: '/index.html',
@@ -22,16 +25,12 @@ class HomePage extends StatelessComponent {
2225
@override
2326
Iterable<Component> build(BuildContext context) sync* {
2427
yield PageLayout(
25-
child: DomComponent(
26-
tag: 'div',
27-
classes: 'home-page',
28-
children: [
29-
_HeroSection(),
30-
_FeaturesSection(),
31-
_CtaSection(),
32-
_FaqSection(),
33-
],
34-
),
28+
children: [
29+
_HeroSection(),
30+
_FeaturesSection(),
31+
_CtaSection(),
32+
_FaqSection(),
33+
],
3534
);
3635
}
3736
}
@@ -53,7 +52,8 @@ class _HeroSection extends StatelessComponent {
5352
div(classes: 'buttons-container', [
5453
a(
5554
classes: 'cta_button',
56-
href: '/builders',
55+
href: BuildersPage.path,
56+
onClick: () => Router.of(context).push(BuildersPage.path),
5757
[text('Explore Builders')],
5858
),
5959
a(

0 commit comments

Comments
 (0)