diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index 253b2bb..0000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,46 +0,0 @@ -permissions: - contents: read -name: Build -on: - push: - branches: - - main - workflow_dispatch: - pull_request: -jobs: - Build-and-Test-CDK: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v5 - - name: Use Node.js - uses: actions/setup-node@v6 - with: - node-version: '22.x' - - run: | - npm ci - npm run format:check - working-directory: ./cdk - name: Install dependencies and run static analysis - - run: | - npm run build - npm run test - working-directory: ./cdk - name: build and test - Build-and-Test-Webapp: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v5 - - name: Use Node.js - uses: actions/setup-node@v6 - with: - node-version: '22.x' - - run: | - npm ci - npm run format:check - working-directory: ./webapp - name: Install dependencies and run static analysis - - run: | - cp .env.local.example .env.local - npm run build - working-directory: ./webapp - name: build diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..4691017 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,23 @@ +name: CI + +on: + push: + branches: + - feature/** + - main + pull_request: + branches: + - main + +jobs: + basic-checks: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Show files + run: ls -la + + - name: Basic validation + run: echo "CI is running for shegxy-webapp" diff --git a/.github/workflows/commitlint.yml b/.github/workflows/commitlint.yml deleted file mode 100644 index 1f55e71..0000000 --- a/.github/workflows/commitlint.yml +++ /dev/null @@ -1,16 +0,0 @@ -name: PR Title - -on: - pull_request_target: - types: [opened, edited, synchronize] - -permissions: - pull-requests: read - -jobs: - lint: - runs-on: ubuntu-latest - steps: - - uses: amannn/action-semantic-pull-request@v6 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/needs-triage.yml b/.github/workflows/needs-triage.yml deleted file mode 100644 index 6d87640..0000000 --- a/.github/workflows/needs-triage.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: Add needs-triage label -on: - issues: - types: [opened] - -permissions: - issues: write - -jobs: - add-label: - if: ${{ !endsWith(github.event.issue.user.login, '[bot]') }} - runs-on: ubuntu-latest - steps: - - uses: actions/github-script@v7 - with: - script: | - await github.rest.issues.addLabels({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: context.issue.number, - labels: ['needs-triage'] - }); diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml deleted file mode 100644 index 08c2655..0000000 --- a/.github/workflows/release-please.yml +++ /dev/null @@ -1,16 +0,0 @@ -on: - push: - branches: - - main - -permissions: - contents: write - pull-requests: write - -name: release-please - -jobs: - release-please: - runs-on: ubuntu-latest - steps: - - uses: googleapis/release-please-action@v4 diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml deleted file mode 100644 index 89e815e..0000000 --- a/.github/workflows/stale.yml +++ /dev/null @@ -1,27 +0,0 @@ -name: Close stale issues and PRs -on: - schedule: - - cron: '0 0 * * *' - -permissions: - issues: write - pull-requests: write - -jobs: - stale: - runs-on: ubuntu-latest - steps: - - uses: actions/stale@v9 - with: - days-before-stale: 60 - days-before-close: 14 - stale-issue-label: stale - stale-pr-label: stale - stale-issue-message: > - This issue has been automatically marked as stale because it has not had - recent activity. It will be closed if no further activity occurs within 14 days. - stale-pr-message: > - This PR has been automatically marked as stale because it has not had - recent activity. It will be closed if no further activity occurs within 14 days. - exempt-issue-labels: 'priority: high' - exempt-pr-labels: 'priority: high' diff --git a/.github/workflows/update_snapshot.yml b/.github/workflows/update_snapshot.yml deleted file mode 100644 index 346526f..0000000 --- a/.github/workflows/update_snapshot.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: Update snapshot - -on: - workflow_dispatch: - push: - branches: - - 'dependabot/**' - issue_comment: - types: [created] - -permissions: - contents: write -jobs: - update: - if: > - github.event_name == 'push' || - github.event_name == 'workflow_dispatch' || - (github.event.issue.pull_request && contains(github.event.comment.body, '/update-snapshot')) - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v5 - with: - ref: ${{ github.event_name == 'issue_comment' && format('refs/pull/{0}/head', github.event.issue.number) || '' }} - - name: Use Node.js - uses: actions/setup-node@v6 - with: - node-version: "22.x" - - run: | - npm ci - npm run test -- -u - working-directory: ./cdk - - name: Add & Commit - uses: EndBug/add-and-commit@v7.2.0 - with: - add: "cdk/test/__snapshots__/." - message: "update snapshot" diff --git a/README.md b/README.md index a262934..a2ca612 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Serverless Full Stack WebApp Starter Kit +# shegxy-webapp [![Build](https://github.com/aws-samples/serverless-full-stack-webapp-starter-kit/actions/workflows/build.yml/badge.svg)](https://github.com/aws-samples/serverless-full-stack-webapp-starter-kit/actions/workflows/build.yml) [![Release](https://img.shields.io/github/v/release/aws-samples/serverless-full-stack-webapp-starter-kit)](https://github.com/aws-samples/serverless-full-stack-webapp-starter-kit/releases) diff --git "a/onalize repo and replace starter workflows\357\200\242" "b/onalize repo and replace starter workflows\357\200\242" new file mode 100644 index 0000000..74570f6 --- /dev/null +++ "b/onalize repo and replace starter workflows\357\200\242" @@ -0,0 +1,324 @@ + + SSUUMMMMAARRYY OOFF LLEESSSS CCOOMMMMAANNDDSS + + Commands marked with * may be preceded by a number, _N. + Notes in parentheses indicate the behavior if _N is given. + A key preceded by a caret indicates the Ctrl key; thus ^K is ctrl-K. + + h H Display this help. + q :q Q :Q ZZ Exit. + --------------------------------------------------------------------------- + + MMOOVVIINNGG + + e ^E j ^N CR * Forward one line (or _N lines). + y ^Y k ^K ^P * Backward one line (or _N lines). + ESC-j * Forward one file line (or _N file lines). + ESC-k * Backward one file line (or _N file lines). + f ^F ^V SPACE * Forward one window (or _N lines). + b ^B ESC-v * Backward one window (or _N lines). + z * Forward one window (and set window to _N). + w * Backward one window (and set window to _N). + ESC-SPACE * Forward one window, but don't stop at end-of-file. + ESC-b * Backward one window, but don't stop at beginning-of-file. + d ^D * Forward one half-window (and set half-window to _N). + u ^U * Backward one half-window (and set half-window to _N). + ESC-) RightArrow * Right one half screen width (or _N positions). + ESC-( LeftArrow * Left one half screen width (or _N positions). + ESC-} ^RightArrow Right to last column displayed. + ESC-{ ^LeftArrow Left to first column. + F Forward forever; like "tail -f". + ESC-F Like F but stop when search pattern is found. + r ^R ^L Repaint screen. + R Repaint screen, discarding buffered input. + --------------------------------------------------- + Default "window" is the screen height. + Default "half-window" is half of the screen height. + --------------------------------------------------------------------------- + + SSEEAARRCCHHIINNGG + + /_p_a_t_t_e_r_n * Search forward for (_N-th) matching line. + ?_p_a_t_t_e_r_n * Search backward for (_N-th) matching line. + n * Repeat previous search (for _N-th occurrence). + N * Repeat previous search in reverse direction. + ESC-n * Repeat previous search, spanning files. + ESC-N * Repeat previous search, reverse dir. & spanning files. + ^O^N ^On * Search forward for (_N-th) OSC8 hyperlink. + ^O^P ^Op * Search backward for (_N-th) OSC8 hyperlink. + ^O^L ^Ol Jump to the currently selected OSC8 hyperlink. + ESC-u Undo (toggle) search highlighting. + ESC-U Clear search highlighting. + &_p_a_t_t_e_r_n * Display only matching lines. + --------------------------------------------------- + Search is case-sensitive unless changed with -i or -I. + A search pattern may begin with one or more of: + ^N or ! Search for NON-matching lines. + ^E or * Search multiple files (pass thru END OF FILE). + ^F or @ Start search at FIRST file (for /) or last file (for ?). + ^K Highlight matches, but don't move (KEEP position). + ^R Don't use REGULAR EXPRESSIONS. + ^S _n Search for match in _n-th parenthesized subpattern. + ^W WRAP search if no match found. + ^L Enter next character literally into pattern. + --------------------------------------------------------------------------- + + JJUUMMPPIINNGG + + g < ESC-< * Go to first line in file (or line _N). + G > ESC-> * Go to last line in file (or line _N). + p % * Go to beginning of file (or _N percent into file). + t * Go to the (_N-th) next tag. + T * Go to the (_N-th) previous tag. + { ( [ * Find close bracket } ) ]. + } ) ] * Find open bracket { ( [. + ESC-^F _<_c_1_> _<_c_2_> * Find close bracket _<_c_2_>. + ESC-^B _<_c_1_> _<_c_2_> * Find open bracket _<_c_1_>. + --------------------------------------------------- + Each "find close bracket" command goes forward to the close bracket + matching the (_N-th) open bracket in the top line. + Each "find open bracket" command goes backward to the open bracket + matching the (_N-th) close bracket in the bottom line. + + m_<_l_e_t_t_e_r_> Mark the current top line with . + M_<_l_e_t_t_e_r_> Mark the current bottom line with . + '_<_l_e_t_t_e_r_> Go to a previously marked position. + '' Go to the previous position. + ^X^X Same as '. + ESC-m_<_l_e_t_t_e_r_> Clear a mark. + --------------------------------------------------- + A mark is any upper-case or lower-case letter. + Certain marks are predefined: + ^ means beginning of the file + $ means end of the file + --------------------------------------------------------------------------- + + CCHHAANNGGIINNGG FFIILLEESS + + :e [_f_i_l_e] Examine a new file. + ^X^V Same as :e. + :n * Examine the (_N-th) next file from the command line. + :p * Examine the (_N-th) previous file from the command line. + :x * Examine the first (or _N-th) file from the command line. + ^O^O Open the currently selected OSC8 hyperlink. + :d Delete the current file from the command line list. + = ^G :f Print current file name. + --------------------------------------------------------------------------- + + MMIISSCCEELLLLAANNEEOOUUSS CCOOMMMMAANNDDSS + + -_<_f_l_a_g_> Toggle a command line option [see OPTIONS below]. + --_<_n_a_m_e_> Toggle a command line option, by name. + __<_f_l_a_g_> Display the setting of a command line option. + ___<_n_a_m_e_> Display the setting of an option, by name. + +_c_m_d Execute the less cmd each time a new file is examined. + + !_c_o_m_m_a_n_d Execute the shell command with $SHELL. + #_c_o_m_m_a_n_d Execute the shell command, expanded like a prompt. + |XX_c_o_m_m_a_n_d Pipe file between current pos & mark XX to shell command. + s _f_i_l_e Save input to a file. + v Edit the current file with $VISUAL or $EDITOR. + V Print version number of "less". + --------------------------------------------------------------------------- + + OOPPTTIIOONNSS + + Most options may be changed either on the command line, + or from within less by using the - or -- command. + Options may be given in one of two forms: either a single + character preceded by a -, or a name preceded by --. + + -? ........ --help + Display help (from command line). + -a ........ --search-skip-screen + Search skips current screen. + -A ........ --SEARCH-SKIP-SCREEN + Search starts just after target line. + -b [_N] .... --buffers=[_N] + Number of buffers. + -B ........ --auto-buffers + Don't automatically allocate buffers for pipes. + -c ........ --clear-screen + Repaint by clearing rather than scrolling. + -d ........ --dumb + Dumb terminal. + -D xx_c_o_l_o_r . --color=xx_c_o_l_o_r + Set screen colors. + -e -E .... --quit-at-eof --QUIT-AT-EOF + Quit at end of file. + -f ........ --force + Force open non-regular files. + -F ........ --quit-if-one-screen + Quit if entire file fits on first screen. + -g ........ --hilite-search + Highlight only last match for searches. + -G ........ --HILITE-SEARCH + Don't highlight any matches for searches. + -h [_N] .... --max-back-scroll=[_N] + Backward scroll limit. + -i ........ --ignore-case + Ignore case in searches that do not contain uppercase. + -I ........ --IGNORE-CASE + Ignore case in all searches. + -j [_N] .... --jump-target=[_N] + Screen position of target lines. + -J ........ --status-column + Display a status column at left edge of screen. + -k _f_i_l_e ... --lesskey-file=_f_i_l_e + Use a compiled lesskey file. + -K ........ --quit-on-intr + Exit less in response to ctrl-C. + -L ........ --no-lessopen + Ignore the LESSOPEN environment variable. + -m -M .... --long-prompt --LONG-PROMPT + Set prompt style. + -n ......... --line-numbers + Suppress line numbers in prompts and messages. + -N ......... --LINE-NUMBERS + Display line number at start of each line. + -o [_f_i_l_e] .. --log-file=[_f_i_l_e] + Copy to log file (standard input only). + -O [_f_i_l_e] .. --LOG-FILE=[_f_i_l_e] + Copy to log file (unconditionally overwrite). + -p _p_a_t_t_e_r_n . --pattern=[_p_a_t_t_e_r_n] + Start at pattern (from command line). + -P [_p_r_o_m_p_t] --prompt=[_p_r_o_m_p_t] + Define new prompt. + -q -Q .... --quiet --QUIET --silent --SILENT + Quiet the terminal bell. + -r -R .... --raw-control-chars --RAW-CONTROL-CHARS + Output "raw" control characters. + -s ........ --squeeze-blank-lines + Squeeze multiple blank lines. + -S ........ --chop-long-lines + Chop (truncate) long lines rather than wrapping. + -t _t_a_g .... --tag=[_t_a_g] + Find a tag. + -T [_t_a_g_s_f_i_l_e] --tag-file=[_t_a_g_s_f_i_l_e] + Use an alternate tags file. + -u -U .... --underline-special --UNDERLINE-SPECIAL + Change handling of backspaces, tabs and carriage returns. + -V ........ --version + Display the version number of "less". + -w ........ --hilite-unread + Highlight first new line after forward-screen. + -W ........ --HILITE-UNREAD + Highlight first new line after any forward movement. + -x [_N[,...]] --tabs=[_N[,...]] + Set tab stops. + -X ........ --no-init + Don't use termcap init/deinit strings. + -y [_N] .... --max-forw-scroll=[_N] + Forward scroll limit. + -z [_N] .... --window=[_N] + Set size of window. + -" [_c[_c]] . --quotes=[_c[_c]] + Set shell quote characters. + -~ ........ --tilde + Don't display tildes after end of file. + -# [_N] .... --shift=[_N] + Set horizontal scroll amount (0 = one half screen width). + + --exit-follow-on-close + Exit F command on a pipe when writer closes pipe. + --file-size + Automatically determine the size of the input file. + --follow-name + The F command changes files if the input file is renamed. + --form-feed + Stop scrolling when a form feed character is reached. + --header=[_L[,_C[,_N]]] + Use _L lines (starting at line _N) and _C columns as headers. + --incsearch + Search file as each pattern character is typed in. + --intr=[_C] + Use _C instead of ^X to interrupt a read. + --lesskey-context=_t_e_x_t + Use lesskey source file contents. + --lesskey-src=_f_i_l_e + Use a lesskey source file. + --line-num-width=[_N] + Set the width of the -N line number field to _N characters. + --match-shift=[_N] + Show at least _N characters to the left of a search match. + --modelines=[_N] + Read _N lines from the input file and look for vim modelines. + --mouse + Enable mouse input. + --no-edit-warn + Don't warn when using v command on a file opened via LESSOPEN. + --no-keypad + Don't send termcap keypad init/deinit strings. + --no-histdups + Remove duplicates from command history. + --no-number-headers + Don't give line numbers to header lines. + --no-paste + Ignore pasted input. + --no-search-header-lines + Searches do not include header lines. + --no-search-header-columns + Searches do not include header columns. + --no-search-headers + Searches do not include header lines or columns. + --no-vbell + Disable the terminal's visual bell. + --redraw-on-quit + Redraw final screen when quitting. + --rscroll=[_C] + Set the character used to mark truncated lines. + --save-marks + Retain marks across invocations of less. + --search-options=[EFKNRW-] + Set default options for every search. + --show-preproc-errors + Display a message if preprocessor exits with an error status. + --proc-backspace + Process backspaces for bold/underline. + --PROC-BACKSPACE + Treat backspaces as control characters. + --proc-return + Delete carriage returns before newline. + --PROC-RETURN + Treat carriage returns as control characters. + --proc-tab + Expand tabs to spaces. + --PROC-TAB + Treat tabs as control characters. + --status-col-width=[_N] + Set the width of the -J status column to _N characters. + --status-line + Highlight or color the entire line containing a mark. + --use-backslash + Subsequent options use backslash as escape char. + --use-color + Enables colored text. + --wheel-lines=[_N] + Each click of the mouse wheel moves _N lines. + --wordwrap + Wrap lines at spaces. + + + --------------------------------------------------------------------------- + + LLIINNEE EEDDIITTIINNGG + + These keys can be used to edit text being entered + on the "command line" at the bottom of the screen. + + RightArrow ..................... ESC-l ... Move cursor right one character. + LeftArrow ...................... ESC-h ... Move cursor left one character. + ctrl-RightArrow ESC-RightArrow ESC-w ... Move cursor right one word. + ctrl-LeftArrow ESC-LeftArrow ESC-b ... Move cursor left one word. + HOME ........................... ESC-0 ... Move cursor to start of line. + END ............................ ESC-$ ... Move cursor to end of line. + BACKSPACE ................................ Delete char to left of cursor. + DELETE ......................... ESC-x ... Delete char under cursor. + ctrl-BACKSPACE ESC-BACKSPACE ........... Delete word to left of cursor. + ctrl-DELETE .... ESC-DELETE .... ESC-X ... Delete word under cursor. + ctrl-U ......... ESC (MS-DOS only) ....... Delete entire line. + UpArrow ........................ ESC-k ... Retrieve previous command line. + DownArrow ...................... ESC-j ... Retrieve next command line. + TAB ...................................... Complete filename & cycle. + SHIFT-TAB ...................... ESC-TAB Complete filename & reverse cycle. + ctrl-L ................................... Complete filename, list all. diff --git a/webapp/prisma/schema.prisma b/webapp/prisma/schema.prisma index da64181..4c339f6 100644 --- a/webapp/prisma/schema.prisma +++ b/webapp/prisma/schema.prisma @@ -25,12 +25,22 @@ enum TodoItemStatus { COMPLETED } +enum TodoItemPriority { + LOW + MEDIUM + HIGH + URGENT +} + model TodoItem { - id String @id @default(uuid()) + id String @id @default(uuid()) title String - description String @db.Text() + description String @db.Text() userId String status TodoItemStatus + priority TodoItemPriority @default(MEDIUM) + dueDate DateTime? + category String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt diff --git a/webapp/src/app/(root)/actions.ts b/webapp/src/app/(root)/actions.ts index 22d7b85..1b862d2 100644 --- a/webapp/src/app/(root)/actions.ts +++ b/webapp/src/app/(root)/actions.ts @@ -10,11 +10,11 @@ import { } from './schemas'; import { prisma } from '@/lib/prisma'; import { revalidatePath } from 'next/cache'; -import { TodoItemStatus } from '@prisma/client'; +import { TodoItemStatus, TodoItemPriority } from '@prisma/client'; import { runJob } from '@/lib/jobs'; export const createTodo = authActionClient.schema(createTodoSchema).action(async ({ parsedInput, ctx }) => { - const { title, description } = parsedInput; + const { title, description, priority, dueDate, category } = parsedInput; const { userId } = ctx; const todo = await prisma.todoItem.create({ @@ -23,6 +23,9 @@ export const createTodo = authActionClient.schema(createTodoSchema).action(async description, userId, status: TodoItemStatus.PENDING, + priority: (priority as TodoItemPriority) || TodoItemPriority.MEDIUM, + dueDate: dueDate ? new Date(dueDate) : null, + category: category || null, }, }); @@ -31,7 +34,7 @@ export const createTodo = authActionClient.schema(createTodoSchema).action(async }); export const updateTodo = authActionClient.schema(updateTodoSchema).action(async ({ parsedInput, ctx }) => { - const { id, title, description, status } = parsedInput; + const { id, title, description, status, priority, dueDate, category } = parsedInput; const { userId } = ctx; const todo = await prisma.todoItem.update({ @@ -43,6 +46,9 @@ export const updateTodo = authActionClient.schema(updateTodoSchema).action(async title, description, status, + ...(priority && { priority: priority as TodoItemPriority }), + ...(dueDate !== undefined && { dueDate: dueDate ? new Date(dueDate) : null }), + ...(category !== undefined && { category: category || null }), }, }); diff --git a/webapp/src/app/(root)/components/CreateTodoForm.tsx b/webapp/src/app/(root)/components/CreateTodoForm.tsx index ed6ea6c..d64cf6b 100644 --- a/webapp/src/app/(root)/components/CreateTodoForm.tsx +++ b/webapp/src/app/(root)/components/CreateTodoForm.tsx @@ -8,6 +8,7 @@ import { createTodoSchema } from '../schemas'; import { toast } from 'sonner'; import { useEventBus } from '@/hooks/use-event-bus'; import { useRouter } from 'next/navigation'; +import { Plus, X, Sparkles, ArrowDown, Minus, AlertTriangle, Flame } from 'lucide-react'; export default function CreateTodoForm(props: { userId: string }) { const [isFormOpen, setIsFormOpen] = useState(false); @@ -22,88 +23,170 @@ export default function CreateTodoForm(props: { userId: string }) { }); const { - form: { register, formState, reset }, + form: { register, formState, reset, setValue, watch }, action, handleSubmitWithAction, } = useHookFormAction(createTodo, zodResolver(createTodoSchema), { actionProps: { onSuccess: () => { - toast.success('Todo created successfully'); + toast.success('Task created successfully'); reset(); setIsFormOpen(false); }, onError: ({ error }) => { - toast.error(typeof error === 'string' ? error : 'Failed to create todo'); + toast.error(typeof error === 'string' ? error : 'Failed to create task'); }, }, formProps: { defaultValues: { title: '', description: '', + priority: 'MEDIUM', + dueDate: '', + category: '', }, }, }); + const selectedPriority = watch('priority'); + + const priorities = [ + { value: 'LOW', label: 'Low', icon: ArrowDown, color: 'text-emerald-400', bg: 'bg-emerald-500/10', border: 'border-emerald-500/30', activeBg: 'bg-emerald-500/20' }, + { value: 'MEDIUM', label: 'Med', icon: Minus, color: 'text-amber-400', bg: 'bg-amber-500/10', border: 'border-amber-500/30', activeBg: 'bg-amber-500/20' }, + { value: 'HIGH', label: 'High', icon: AlertTriangle, color: 'text-orange-400', bg: 'bg-orange-500/10', border: 'border-orange-500/30', activeBg: 'bg-orange-500/20' }, + { value: 'URGENT', label: 'Urgent', icon: Flame, color: 'text-red-400', bg: 'bg-red-500/10', border: 'border-red-500/30', activeBg: 'bg-red-500/20' }, + ]; + if (!isFormOpen) { return (
); } return ( -
-

Create New Todo

+
+
+ +

Create New Task

+
+
+ {/* Title */}
-
+ {/* Description */}
-