gemstack-cli 0.2.5 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +3 -25
- data/README.md +6 -17
- data/exe/gemstack +8 -1
- metadata +6 -159
- data/lib/gemstack/cli/add_generator.rb +0 -239
- data/lib/gemstack/cli/app_generator.rb +0 -142
- data/lib/gemstack/cli/commands/db.rb +0 -135
- data/lib/gemstack/cli/commands/jobs.rb +0 -96
- data/lib/gemstack/cli/controller_generator.rb +0 -73
- data/lib/gemstack/cli/deploy_generator.rb +0 -102
- data/lib/gemstack/cli/doctor.rb +0 -308
- data/lib/gemstack/cli/generator.rb +0 -144
- data/lib/gemstack/cli/job_generator.rb +0 -48
- data/lib/gemstack/cli/migration_generator.rb +0 -52
- data/lib/gemstack/cli/policy_generator.rb +0 -35
- data/lib/gemstack/cli/project.rb +0 -53
- data/lib/gemstack/cli/resource_generator.rb +0 -170
- data/lib/gemstack/cli/resource_spec.rb +0 -95
- data/lib/gemstack/cli.rb +0 -304
- data/templates/app/Gemfile.tt +0 -44
- data/templates/app/README.md.tt +0 -29
- data/templates/app/app/controllers/application_controller.rb +0 -6
- data/templates/app/app/jobs/application_job.rb +0 -9
- data/templates/app/app/mailers/application_mailer.rb +0 -8
- data/templates/app/app/mailers/templates/dot_keep +0 -0
- data/templates/app/app/models/application_model.rb +0 -19
- data/templates/app/app/serializers/application_serializer.rb +0 -6
- data/templates/app/bin/gemstack +0 -7
- data/templates/app/config/app.rb.tt +0 -54
- data/templates/app/config/database.yml.tt +0 -61
- data/templates/app/config/environments/development.rb.tt +0 -35
- data/templates/app/config/environments/production.rb.tt +0 -40
- data/templates/app/config/environments/test.rb.tt +0 -21
- data/templates/app/config/puma.rb +0 -21
- data/templates/app/config/routes.rb +0 -10
- data/templates/app/config.ru +0 -6
- data/templates/app/db/migrations/dot_keep +0 -0
- data/templates/app/db/seeds.rb +0 -5
- data/templates/app/dot_env.example.tt +0 -19
- data/templates/app/dot_gitignore +0 -16
- data/templates/app/dot_node-version.tt +0 -1
- data/templates/app/dot_nvmrc.tt +0 -1
- data/templates/app/dot_ruby-version.tt +0 -1
- data/templates/app/dot_tool-versions.tt +0 -4
- data/templates/app/test/health_test.rb +0 -18
- data/templates/app/test/test_helper.rb.tt +0 -25
- data/templates/auth/app/controllers/api_tokens_controller.rb +0 -35
- data/templates/auth/app/controllers/email_verifications_controller.rb +0 -31
- data/templates/auth/app/controllers/password_resets_controller.rb +0 -40
- data/templates/auth/app/controllers/registrations_controller.rb +0 -19
- data/templates/auth/app/controllers/sessions_controller.rb +0 -29
- data/templates/auth/app/mailers/auth_mailer.rb +0 -20
- data/templates/auth/app/mailers/templates/auth_mailer/email_verification.html.erb +0 -2
- data/templates/auth/app/mailers/templates/auth_mailer/email_verification.text.erb +0 -2
- data/templates/auth/app/mailers/templates/auth_mailer/password_reset.html.erb +0 -3
- data/templates/auth/app/mailers/templates/auth_mailer/password_reset.text.erb +0 -6
- data/templates/auth/app/models/auth_token.rb +0 -15
- data/templates/auth/app/models/user.rb +0 -12
- data/templates/auth/app/policies/application_policy.rb +0 -6
- data/templates/auth/app/serializers/api_token_serializer.rb +0 -6
- data/templates/auth/app/serializers/new_api_token_serializer.rb +0 -9
- data/templates/auth/app/serializers/user_serializer.rb +0 -6
- data/templates/auth/db/migrations/%timestamp%_create_auth_tables.rb +0 -41
- data/templates/auth/frontend/app/account/page.tsx +0 -116
- data/templates/auth/frontend/app/forgot-password/page.tsx +0 -48
- data/templates/auth/frontend/app/login/page.tsx +0 -26
- data/templates/auth/frontend/app/reset-password/page.tsx +0 -11
- data/templates/auth/frontend/app/signup/page.tsx +0 -27
- data/templates/auth/frontend/app/verify-email/page.tsx +0 -11
- data/templates/auth/frontend/components/auth/CredentialsForm.tsx +0 -58
- data/templates/auth/frontend/components/auth/ResetPasswordForm.tsx +0 -43
- data/templates/auth/frontend/components/auth/VerifyEmail.tsx +0 -28
- data/templates/auth/frontend/lib/auth.ts +0 -113
- data/templates/auth/test/controllers/auth_test.rb +0 -108
- data/templates/controller/app/controllers/%file_name%_controller.rb.tt +0 -10
- data/templates/controller/test/controllers/%file_name%_controller_test.rb.tt +0 -14
- data/templates/deploy/Caddyfile.tt +0 -19
- data/templates/deploy/Dockerfile.tt +0 -63
- data/templates/deploy/Procfile.tt +0 -6
- data/templates/deploy/compose.yaml.tt +0 -129
- data/templates/deploy/dot_dockerignore +0 -14
- data/templates/frontend/app/globals.css +0 -171
- data/templates/frontend/app/layout.tsx.tt +0 -19
- data/templates/frontend/app/page.module.css +0 -315
- data/templates/frontend/app/page.tsx.tt +0 -183
- data/templates/frontend/app/providers.tsx +0 -24
- data/templates/frontend/lib/gemstack/client.ts +0 -125
- data/templates/frontend/next-env.d.ts +0 -5
- data/templates/frontend/next.config.ts +0 -17
- data/templates/frontend/package.json.tt +0 -23
- data/templates/frontend/tsconfig.json +0 -21
- data/templates/job/app/jobs/%file_name%.rb.tt +0 -15
- data/templates/job/test/jobs/%file_name%_test.rb.tt +0 -15
- data/templates/migration/db/migrations/%timestamp%_%file_name%.rb.tt +0 -17
- data/templates/policy/app/policies/%file_name%_policy.rb.tt +0 -21
- data/templates/policy/test/policies/%file_name%_policy_test.rb.tt +0 -9
- data/templates/realtime/config/channels.rb +0 -14
- data/templates/realtime/frontend/lib/gemstack/realtime.ts +0 -120
- data/templates/resource/controller/app/controllers/%plural%_controller.rb.tt +0 -51
- data/templates/resource/controller/test/controllers/%plural%_controller_test.rb.tt +0 -74
- data/templates/resource/frontend/frontend/app/%url_segment%/[id]/edit/page.tsx.tt +0 -45
- data/templates/resource/frontend/frontend/app/%url_segment%/[id]/page.tsx.tt +0 -49
- data/templates/resource/frontend/frontend/app/%url_segment%/new/page.tsx.tt +0 -27
- data/templates/resource/frontend/frontend/app/%url_segment%/page.tsx.tt +0 -51
- data/templates/resource/frontend/frontend/components/%url_segment%/%class_name%Card.tsx.tt +0 -15
- data/templates/resource/frontend/frontend/components/%url_segment%/%class_name%Form.tsx.tt +0 -98
- data/templates/resource/frontend/frontend/components/%url_segment%/%class_name%Table.tsx.tt +0 -36
- data/templates/resource/frontend/frontend/lib/format.ts +0 -12
- data/templates/resource/frontend/frontend/lib/queries/%url_segment%.ts.tt +0 -64
- data/templates/resource/migration/db/migrations/%timestamp%_create_%table%.rb.tt +0 -18
- data/templates/resource/model/app/models/%file_name%.rb.tt +0 -15
- data/templates/resource/model/test/models/%file_name%_test.rb.tt +0 -29
- data/templates/resource/serializer/app/serializers/%file_name%_serializer.rb.tt +0 -7
- data/templates/storage/app/controllers/uploads_controller.rb.tt +0 -33
- data/templates/storage/app/serializers/upload_serializer.rb +0 -11
- data/templates/storage/frontend/lib/upload.ts +0 -52
- data/templates/storage/test/controllers/uploads_test.rb.tt +0 -30
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative "<%= "../" * (file_name.count("/") + 1) %>test_helper"
|
|
4
|
-
|
|
5
|
-
class <%= class_name %>Test < GemStack::TestCase
|
|
6
|
-
<% actions.each_with_index do |action, index| -%>
|
|
7
|
-
<%= "\n" if index.positive? %> def test_<%= action %>
|
|
8
|
-
<%= route_for(action)[0] %>_json "<%= request_path(action) %>"
|
|
9
|
-
|
|
10
|
-
assert_status 200
|
|
11
|
-
assert_equal({ "action" => "<%= file_name %>#<%= action %>" }, json_body)
|
|
12
|
-
end
|
|
13
|
-
<% end -%>
|
|
14
|
-
end
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
# One public origin: /api/* → Ruby, everything else → Next.js (docs/deployment.md).
|
|
2
|
-
# SITE_ADDRESS=example.com gets a Let's Encrypt certificate automatically;
|
|
3
|
-
# "localhost" uses Caddy's local CA (trust it with `caddy trust`, or curl -k).
|
|
4
|
-
{$SITE_ADDRESS:localhost} {
|
|
5
|
-
encode zstd gzip
|
|
6
|
-
|
|
7
|
-
handle /api/* {
|
|
8
|
-
reverse_proxy api:4000 {
|
|
9
|
-
# Server-Sent Events: stream responses immediately.
|
|
10
|
-
flush_interval -1
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
<% if frontend? -%>
|
|
14
|
-
|
|
15
|
-
handle {
|
|
16
|
-
reverse_proxy web:3000
|
|
17
|
-
}
|
|
18
|
-
<% end -%>
|
|
19
|
-
}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
# syntax=docker/dockerfile:1
|
|
2
|
-
# Production images for <%= app_name %> (gemstack generate deploy — docs/deployment.md).
|
|
3
|
-
#
|
|
4
|
-
# docker build --target api -t <%= app_name %>-api . # Ruby API (Puma), also runs jobs and migrations
|
|
5
|
-
<% if frontend? -%>
|
|
6
|
-
# docker build --target web -t <%= app_name %>-web . # Next.js
|
|
7
|
-
<% end -%>
|
|
8
|
-
#
|
|
9
|
-
# Configuration comes from the environment at runtime (SECRET_KEY_BASE,
|
|
10
|
-
# DATABASE_URL, …); nothing secret is baked into the images.
|
|
11
|
-
|
|
12
|
-
ARG RUBY_VERSION=<%= ruby_version %>
|
|
13
|
-
ARG NODE_VERSION=<%= node_version %>
|
|
14
|
-
|
|
15
|
-
# ── Ruby API ────────────────────────────────────────────────────────────────
|
|
16
|
-
FROM ruby:${RUBY_VERSION}-slim AS api-build
|
|
17
|
-
RUN apt-get update -qq && apt-get install --no-install-recommends -y <%= build_packages %> \
|
|
18
|
-
&& rm -rf /var/lib/apt/lists/*
|
|
19
|
-
WORKDIR /app
|
|
20
|
-
ENV BUNDLE_DEPLOYMENT=1 BUNDLE_WITHOUT="development:test" BUNDLE_PATH=/usr/local/bundle
|
|
21
|
-
COPY Gemfile Gemfile.lock ./
|
|
22
|
-
COPY vendor/ ./vendor/
|
|
23
|
-
RUN bundle install --jobs 4 && rm -rf /usr/local/bundle/cache "${BUNDLE_PATH}"/ruby/*/cache
|
|
24
|
-
COPY . .
|
|
25
|
-
RUN rm -rf frontend tmp/* log/* .env*
|
|
26
|
-
|
|
27
|
-
FROM ruby:${RUBY_VERSION}-slim AS api
|
|
28
|
-
RUN apt-get update -qq && apt-get install --no-install-recommends -y <%= runtime_packages %> \
|
|
29
|
-
&& rm -rf /var/lib/apt/lists/* \
|
|
30
|
-
&& groupadd --system --gid 1000 app && useradd --system --uid 1000 --gid app --create-home app<% if sqlite? %> \
|
|
31
|
-
&& mkdir -p /data && chown app:app /data<% end %>
|
|
32
|
-
WORKDIR /app
|
|
33
|
-
ENV GEMSTACK_ENV=production BUNDLE_DEPLOYMENT=1 BUNDLE_WITHOUT="development:test" BUNDLE_PATH=/usr/local/bundle \
|
|
34
|
-
GEMSTACK_API_HOST=0.0.0.0 GEMSTACK_API_PORT=4000
|
|
35
|
-
COPY --from=api-build /usr/local/bundle /usr/local/bundle
|
|
36
|
-
COPY --from=api-build --chown=app:app /app /app
|
|
37
|
-
USER app
|
|
38
|
-
EXPOSE 4000
|
|
39
|
-
HEALTHCHECK --interval=10s --timeout=3s --start-period=20s CMD curl -fsS http://127.0.0.1:4000/api/health || exit 1
|
|
40
|
-
# Other processes use the same image: `bundle exec gemstack jobs`, `bundle exec gemstack db:migrate`.
|
|
41
|
-
CMD ["bundle", "exec", "puma", "-C", "config/puma.rb"]
|
|
42
|
-
<% if frontend? -%>
|
|
43
|
-
|
|
44
|
-
# ── Next.js ─────────────────────────────────────────────────────────────────
|
|
45
|
-
FROM node:${NODE_VERSION}-slim AS web-build
|
|
46
|
-
WORKDIR /app
|
|
47
|
-
COPY frontend/package.json frontend/package-lock.json ./
|
|
48
|
-
RUN npm ci
|
|
49
|
-
COPY frontend/ ./
|
|
50
|
-
ENV NEXT_TELEMETRY_DISABLED=1
|
|
51
|
-
# GEMSTACK_API_URL is only needed here when Next.js proxies /api itself (no reverse proxy in front).
|
|
52
|
-
ARG GEMSTACK_API_URL
|
|
53
|
-
ENV GEMSTACK_API_URL=${GEMSTACK_API_URL}
|
|
54
|
-
RUN npm run build && npm prune --omit=dev
|
|
55
|
-
|
|
56
|
-
FROM node:${NODE_VERSION}-slim AS web
|
|
57
|
-
WORKDIR /app
|
|
58
|
-
ENV NODE_ENV=production NEXT_TELEMETRY_DISABLED=1 PORT=3000
|
|
59
|
-
COPY --from=web-build --chown=node:node /app ./
|
|
60
|
-
USER node
|
|
61
|
-
EXPOSE 3000
|
|
62
|
-
CMD ["npm", "start"]
|
|
63
|
-
<% end -%>
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
# Process types for Procfile platforms (Heroku, Render, Railway, Dokku…) — docs/deployment.md.
|
|
2
|
-
release: bundle exec gemstack db:migrate
|
|
3
|
-
web: GEMSTACK_API_PORT=${PORT:-4000} bundle exec puma -C config/puma.rb
|
|
4
|
-
<% if jobs? -%>
|
|
5
|
-
worker: bundle exec gemstack jobs
|
|
6
|
-
<% end -%>
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
# Runs <%= app_name %> in production mode on this machine, behind Caddy on https://localhost:
|
|
2
|
-
#
|
|
3
|
-
# export SECRET_KEY_BASE=$(openssl rand -hex 64)<% if postgresql? %> POSTGRES_PASSWORD=$(openssl rand -hex 16)<% elsif mysql? %> MYSQL_PASSWORD=$(openssl rand -hex 16)<% end %>
|
|
4
|
-
# docker compose up --build
|
|
5
|
-
#
|
|
6
|
-
# It's also a map of what a real deploy needs: one image per process type,
|
|
7
|
-
# migrations before the API starts, and a proxy sending /api to Ruby.
|
|
8
|
-
<% if sqlite? -%>
|
|
9
|
-
# SQLite: the database file lives on the `data` volume, shared by the API, the
|
|
10
|
-
# jobs worker and migrations — keep them on one host.
|
|
11
|
-
<% end -%>
|
|
12
|
-
name: <%= app_name.tr("_", "-") %>
|
|
13
|
-
|
|
14
|
-
x-api-env: &api-env
|
|
15
|
-
GEMSTACK_ENV: production
|
|
16
|
-
SECRET_KEY_BASE: ${SECRET_KEY_BASE:?set SECRET_KEY_BASE (openssl rand -hex 64)}
|
|
17
|
-
<% if database? -%>
|
|
18
|
-
DATABASE_URL: <%= database_url %>
|
|
19
|
-
<% end -%>
|
|
20
|
-
<% if redis? -%>
|
|
21
|
-
REDIS_URL: redis://redis:6379/0 # realtime fan-out between the API and the jobs worker
|
|
22
|
-
<% end -%>
|
|
23
|
-
APP_URL: ${APP_URL:-https://localhost}
|
|
24
|
-
<% if mail? -%>
|
|
25
|
-
SMTP_URL: ${SMTP_URL:-} # e.g. smtp://user:pass@smtp.example.com:587 — emails retry until it is set
|
|
26
|
-
MAIL_FROM: ${MAIL_FROM:-}
|
|
27
|
-
<% end -%>
|
|
28
|
-
|
|
29
|
-
services:
|
|
30
|
-
<% if postgresql? -%>
|
|
31
|
-
db:
|
|
32
|
-
image: postgres:17
|
|
33
|
-
environment:
|
|
34
|
-
POSTGRES_USER: app
|
|
35
|
-
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?set POSTGRES_PASSWORD}
|
|
36
|
-
POSTGRES_DB: app
|
|
37
|
-
volumes: [db:/var/lib/postgresql/data]
|
|
38
|
-
healthcheck:
|
|
39
|
-
test: ["CMD-SHELL", "pg_isready -U app -d app"]
|
|
40
|
-
interval: 2s
|
|
41
|
-
retries: 30
|
|
42
|
-
|
|
43
|
-
<% elsif mysql? -%>
|
|
44
|
-
db:
|
|
45
|
-
image: mysql:8.4
|
|
46
|
-
environment:
|
|
47
|
-
MYSQL_DATABASE: app
|
|
48
|
-
MYSQL_USER: app
|
|
49
|
-
MYSQL_PASSWORD: ${MYSQL_PASSWORD:?set MYSQL_PASSWORD}
|
|
50
|
-
MYSQL_RANDOM_ROOT_PASSWORD: "yes"
|
|
51
|
-
volumes: [db:/var/lib/mysql]
|
|
52
|
-
healthcheck:
|
|
53
|
-
test: ["CMD-SHELL", "mysqladmin ping -h 127.0.0.1 -uapp -p$$MYSQL_PASSWORD --silent"]
|
|
54
|
-
interval: 3s
|
|
55
|
-
retries: 40
|
|
56
|
-
|
|
57
|
-
<% end -%>
|
|
58
|
-
<% if redis? -%>
|
|
59
|
-
redis:
|
|
60
|
-
image: redis:7
|
|
61
|
-
command: ["redis-server", "--save", "", "--appendonly", "no"]
|
|
62
|
-
|
|
63
|
-
<% end -%>
|
|
64
|
-
<% if database? -%>
|
|
65
|
-
migrate:
|
|
66
|
-
image: <%= app_name %>-api
|
|
67
|
-
build: { context: ., target: api }
|
|
68
|
-
healthcheck: { disable: true }
|
|
69
|
-
command: ["bundle", "exec", "gemstack", "db:migrate"]
|
|
70
|
-
environment: *api-env
|
|
71
|
-
<% if sqlite? -%>
|
|
72
|
-
volumes: [data:/data]
|
|
73
|
-
<% else -%>
|
|
74
|
-
depends_on: { db: { condition: service_healthy } }
|
|
75
|
-
<% end -%>
|
|
76
|
-
|
|
77
|
-
<% end -%>
|
|
78
|
-
api:
|
|
79
|
-
image: <%= app_name %>-api
|
|
80
|
-
build: { context: ., target: api }
|
|
81
|
-
environment:
|
|
82
|
-
<<: *api-env
|
|
83
|
-
WEB_CONCURRENCY: ${WEB_CONCURRENCY:-2}
|
|
84
|
-
<% if sqlite? -%>
|
|
85
|
-
volumes: [data:/data]
|
|
86
|
-
<% end -%>
|
|
87
|
-
<% if database? -%>
|
|
88
|
-
depends_on: { migrate: { condition: service_completed_successfully } }
|
|
89
|
-
<% end -%>
|
|
90
|
-
<% if jobs? -%>
|
|
91
|
-
|
|
92
|
-
jobs:
|
|
93
|
-
image: <%= app_name %>-api
|
|
94
|
-
build: { context: ., target: api }
|
|
95
|
-
healthcheck: { disable: true }
|
|
96
|
-
command: ["bundle", "exec", "gemstack", "jobs"]
|
|
97
|
-
environment: *api-env
|
|
98
|
-
<% if sqlite? -%>
|
|
99
|
-
volumes: [data:/data]
|
|
100
|
-
<% end -%>
|
|
101
|
-
depends_on: { migrate: { condition: service_completed_successfully } }
|
|
102
|
-
<% end -%>
|
|
103
|
-
<% if frontend? -%>
|
|
104
|
-
|
|
105
|
-
web:
|
|
106
|
-
image: <%= app_name %>-web
|
|
107
|
-
build: { context: ., target: web }
|
|
108
|
-
environment:
|
|
109
|
-
GEMSTACK_API_URL: http://api:4000 # Server Components call the API directly
|
|
110
|
-
depends_on: [api]
|
|
111
|
-
<% end -%>
|
|
112
|
-
|
|
113
|
-
proxy:
|
|
114
|
-
image: caddy:2
|
|
115
|
-
ports: ["80:80", "443:443"]
|
|
116
|
-
environment:
|
|
117
|
-
SITE_ADDRESS: ${SITE_ADDRESS:-localhost}
|
|
118
|
-
volumes:
|
|
119
|
-
- ./Caddyfile:/etc/caddy/Caddyfile:ro
|
|
120
|
-
- caddy:/data
|
|
121
|
-
depends_on: [api<%= ", web" if frontend? %>]
|
|
122
|
-
|
|
123
|
-
volumes:
|
|
124
|
-
<% if sqlite? -%>
|
|
125
|
-
data:
|
|
126
|
-
<% elsif database? -%>
|
|
127
|
-
db:
|
|
128
|
-
<% end -%>
|
|
129
|
-
caddy:
|
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
:root {
|
|
2
|
-
--bg: #ffffff;
|
|
3
|
-
--fg: #16181d;
|
|
4
|
-
--muted: #5b6170;
|
|
5
|
-
--code-bg: #f1f2f5;
|
|
6
|
-
--ok: #1f9d55;
|
|
7
|
-
--error: #d64545;
|
|
8
|
-
--pending: #d99a1e;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
@media (prefers-color-scheme: dark) {
|
|
12
|
-
:root {
|
|
13
|
-
--bg: #0f1115;
|
|
14
|
-
--fg: #e6e8ee;
|
|
15
|
-
--muted: #9aa0ad;
|
|
16
|
-
--code-bg: #1c2030;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
* {
|
|
21
|
-
box-sizing: border-box;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
body {
|
|
25
|
-
margin: 0;
|
|
26
|
-
background: var(--bg);
|
|
27
|
-
color: var(--fg);
|
|
28
|
-
font: 16px/1.6 system-ui, -apple-system, "Segoe UI", sans-serif;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
code {
|
|
32
|
-
background: var(--code-bg);
|
|
33
|
-
padding: 0.1rem 0.35rem;
|
|
34
|
-
border-radius: 4px;
|
|
35
|
-
font-size: 0.9em;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
.page {
|
|
39
|
-
max-width: 40rem;
|
|
40
|
-
margin: 0 auto;
|
|
41
|
-
padding: 4rem 1rem;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
.muted {
|
|
45
|
-
color: var(--muted);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
.status {
|
|
49
|
-
display: flex;
|
|
50
|
-
align-items: center;
|
|
51
|
-
gap: 0.6rem;
|
|
52
|
-
padding: 0.75rem 1rem;
|
|
53
|
-
border-radius: 8px;
|
|
54
|
-
background: var(--code-bg);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
.dot {
|
|
58
|
-
width: 0.6rem;
|
|
59
|
-
height: 0.6rem;
|
|
60
|
-
border-radius: 50%;
|
|
61
|
-
flex: none;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
.status-ok .dot {
|
|
65
|
-
background: var(--ok);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
.status-error .dot {
|
|
69
|
-
background: var(--error);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
.status-pending .dot {
|
|
73
|
-
background: var(--pending);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
a {
|
|
77
|
-
color: inherit;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
h1 {
|
|
81
|
-
margin-top: 0;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
.page-header,
|
|
85
|
-
.actions {
|
|
86
|
-
display: flex;
|
|
87
|
-
align-items: center;
|
|
88
|
-
justify-content: space-between;
|
|
89
|
-
gap: 1rem;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
.actions {
|
|
93
|
-
justify-content: flex-start;
|
|
94
|
-
margin-top: 1.5rem;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
.button {
|
|
98
|
-
display: inline-block;
|
|
99
|
-
padding: 0.45rem 0.9rem;
|
|
100
|
-
border: 1px solid var(--fg);
|
|
101
|
-
border-radius: 6px;
|
|
102
|
-
background: var(--fg);
|
|
103
|
-
color: var(--bg);
|
|
104
|
-
font: inherit;
|
|
105
|
-
text-decoration: none;
|
|
106
|
-
cursor: pointer;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
.button:disabled {
|
|
110
|
-
opacity: 0.6;
|
|
111
|
-
cursor: default;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
.button-danger {
|
|
115
|
-
background: var(--error);
|
|
116
|
-
border-color: var(--error);
|
|
117
|
-
color: #fff;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
.table {
|
|
121
|
-
width: 100%;
|
|
122
|
-
border-collapse: collapse;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
.table th,
|
|
126
|
-
.table td {
|
|
127
|
-
padding: 0.5rem;
|
|
128
|
-
border-bottom: 1px solid var(--code-bg);
|
|
129
|
-
text-align: left;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
.form {
|
|
133
|
-
display: grid;
|
|
134
|
-
gap: 1rem;
|
|
135
|
-
max-width: 32rem;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
.field {
|
|
139
|
-
display: grid;
|
|
140
|
-
gap: 0.3rem;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
.field input:not([type="checkbox"]),
|
|
144
|
-
.field textarea {
|
|
145
|
-
padding: 0.45rem;
|
|
146
|
-
border: 1px solid var(--muted);
|
|
147
|
-
border-radius: 6px;
|
|
148
|
-
background: var(--bg);
|
|
149
|
-
color: var(--fg);
|
|
150
|
-
font: inherit;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
.field-error,
|
|
154
|
-
.form-error {
|
|
155
|
-
margin: 0;
|
|
156
|
-
color: var(--error);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
.card {
|
|
160
|
-
display: grid;
|
|
161
|
-
grid-template-columns: max-content 1fr;
|
|
162
|
-
gap: 0.4rem 1.5rem;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
.card dt {
|
|
166
|
-
color: var(--muted);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
.card dd {
|
|
170
|
-
margin: 0;
|
|
171
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { Metadata } from "next";
|
|
2
|
-
import type { ReactNode } from "react";
|
|
3
|
-
import { Providers } from "./providers";
|
|
4
|
-
import "./globals.css";
|
|
5
|
-
|
|
6
|
-
export const metadata: Metadata = {
|
|
7
|
-
title: "<%= module_name %>",
|
|
8
|
-
description: "A GemStack application",
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export default function RootLayout({ children }: { children: ReactNode }) {
|
|
12
|
-
return (
|
|
13
|
-
<html lang="en">
|
|
14
|
-
<body>
|
|
15
|
-
<Providers>{children}</Providers>
|
|
16
|
-
</body>
|
|
17
|
-
</html>
|
|
18
|
-
);
|
|
19
|
-
}
|